개발 기술/개발 이야기

프로토타입이란? (feat. 순한 맛 🌝)

by GicoMomg (Lux) 2021. 11. 2.

프로토타입은 무엇이며, 어떻게 사용하면 좋을까? 이 포스팅에서는 프로토타입에 대해 순하게 알아본다.



1. 프로토타입

(1) 프로토타입이란?

  • js언어를 공부할 때 우리는 프로토타입이라는 단어를 듣게 된다.
  • 프로토타입을 그대로 번역하면 '원형'이라고 해석되는데, 말 그대로 객체의 원형이다.
  • 우리는 js에서 array, object와 같은 객체를 생성할 수 있다.
  • 이때 생성된 객체는 사용자가 메소드를 추가하지 않았지만, arrayobject의 메소드를 쓸 수 있게 된다.

그 이유는 무엇일까? 그건 바로 프로토타입에 원형의 정보가 담겨있기 때문이다.

  • 사용자가 A객체를 이용해 B객체를 생성하면 그와 동시에 B객체에 프로토타입(B에 대한 정보)이 추가된다.

  • 생성된 객체(B)는 프로토타입에 접근할 수 있으며, 프로토타입에는 객체의 원형(A)의 정보가 담겨있다.

  • 만약 원형(A)에서 print라는 메소드를 정의했으면, 이 print메소드를 가져와 쓸 수 있다는 말이다.

  • 말로만 설명해서 조금 어려운 감이 있는데 아래 예시도 살펴보자.



(2) 프로토타입 예시1, 배열의 경우

  • 우리는 프로토타입의 이점을 많이 접하고 있다.
  • 하나의 예시로 배열을 만들어보자.
const arr = [];

  • arr라는 변수는 배열 객체이며, 사용할 수 있는 메소드는 사진과 같이 알 수 있다.


  • 이처럼 배열인 arr가 접근할 수 있는 메소드는 어디서 온걸까?
  • 그건 바로 arr의 프로토타입에 Array의 메소드 정보도 저장되어 있기 때문이다.

  • 프로토타입을 사용하게 되면 원형이 제공하는 메소드나 변수에 접근할 수 있다.



(3) 프로토타입 예시2, 중복을 줄이기

  • 아래와 같이 admin, user 객체가 존재하며, 이 두 객체는 중복 속성을 가지고 있다.
const user = { name: 'a', age: 100};
const admin = { name: 'a', age: 100, role: 'admin' };

만약 객체 간 중복 속성이 존재한다면 어떻게 하면 중복을 줄일 수 있을까?
방법은 바로 프로토타입을 사용하는 것이다.

  • 프로토타입은, A객체가 B객체의 속성을 사용할 수 있도록 연결해주는 역할도 한다.
  • 프로토타입에 저장된 속성은 객체 생성시 생성자를 통해 해당 객체에 연결(상속)된다.
const user = { name: 'a', age: 100 };

let admin = {}
admin.__proto__ = user;    //프로토타입에 user의 정보를 저장

  • 위와 같은 작업을 거치면, admin에서 user의 속성을 상속받아 쓸 수 있다.
console.log(admin) 



(3) 프로토타입 예시3, 클래스에서 프로토타입 쓰는 방법

  • 클래스가 추가되기 전 우리는 생성자를 사용했다. (생성자와 클래스의 차이가 헷갈린다면 이 포스팅 참고)
  • 생성자를 사용해 아래와 같이 새로운 객체를 만들 수 있다.
function Person(name, age) {
  this.name = name;
  this.age = age;
}
const lili = new Person('lili', 100);
console.log(lili);  // Person {name: 'lili', age: 40}

  • 하지만 ES6부터는 생성자 대신 사용할 수 있는 클래스가 추가되었다.
class Person {
  constructor(name, age) {
      this.name = name;
    this.age = age;
  }
}

const lili = new Person('lili', 40);  
console.log(lili);    // Person {name: 'lili', age: 40}

그럼 이 클래스와 프로토타입은 무슨 연관이 있을까?

  • 앞서 언급했듯이, 프로토타입은 원형의 메소드, 속성 정보를 담고 있다.
  • 클래스를 정의한다는 건, 이 클래스를 기반으로 다른 객체를 만든다는 말이 된다.
  • 그렇다면 이 클래스를 원형으로 만들어질 객체에 기본으로 제공하고 싶은 메소드가 있다면?
  • 클래스 내부에 메소드를 추가하면 된다.
  • 아래와 같이 메소드를 추가하면 자동으로 프로토타입에 등록된다.
class Person {
  constructor(name, age) {
      this.name = name;
    this.age = age;
  }
  print() {         //prototype에 저장
    return 'hello'
  }
}



반응형

댓글