[코어 자바스크립트] 06 프로토타입

백은진·2021년 2월 21일
2

06 프로토타입

챕터 목표: 프로토타입에 대해 알고, 큼직하게 개념을 이해한다.

(prototype = 원형)

자바스크립트는 프로토타입 기반 언어이다. 클래스 기반 언어에서는 '상속' 개념을 사용하는 반면, 프로토타입 기반 언아에서는 어떤 객체를 원형으로 삼고 이를 복제/참조함으로써 상속과 비슷한 효과를 얻는다.

프로토타입을 이해하는 것은 어렵지만, 알고 난 후엔 매우 쉽게 느껴지기도 한다. 이 프로토타입 개념을 제대로 이해한다는 것은 숙련자 레벨에 도달할 수 있다는 것과 같으므로 두려워 말고 잘 이해해보자.


1. 프로토타입의 개념 이해

1-1. constructor, prototype, instance

var instance = new Contructor();
  1. 어떤 Constructor(생성자 함수)를 new 연산자와 함께 호출하면
  2. Constructor에서 정의된 내용을 바탕으로 새로운 instance가 생성된다.
  3. 이때 instance에는 __proto__라는 프로퍼티가 자동으로 부여되는데,
  4. 이 프로퍼티는 Constructor의 prototype이라는 프로퍼티를 참조한다.

위의 1~4 글에서 가장 중요한 것은 prototype이라는 프로퍼티와 __proto__라는 프로퍼티이다. 이 둘의 관계가 프로토타입 개념의 핵심이다.

prototype은 객체이다. 이를 참조하는 __proto__ 역시 객체이다. prototype 객체 내부에는 인스턴스가 사용할 메서드를 저장한다. 그러면 인스턴스에서도 숨겨진 프로퍼티인 __proto__를 통해 이 메서드들에 접근할 수 있게 된다.

(주석: __proto__는 '던더 프로토'라고 발음한다고 한다. dunder는 double underscore의 약자다.)

(주석2: ES5.1 명세에는 __proto__가 아닌 [[prototype]]이라는 명칭으로 정의되어 있다. 전자는 브라우저가 후자를 구현한 대상에 지나지 않는다. 또한, 명세에서 instance.__proto__ 방식으로 접근하는 것을 허용하지 않고, Object.getPrototypeOf(instance)/Refelect.getPrototypeOf(instance)를 통해서만 접근하도록 정의했다. 실무에서는 되도록 __proto__가 아닌 Object.getPrototypeOf()/Object.create()를 이용하자.)

예제 1 ) Person.prototype

var Person = function (name) {
  this._name = name;
};

Person.prototype.getName = function() {
  return this._name;
};

var suzi = new Person('Suzi');
console.log(suzi.__proto__.getName());  // undefined

Person.prototype === suzi.__proto__  // true

.getName() 메서드의 호출 결과로 undefined가 출력됐다. 'Suzy'라는 값이 나오지 않은 것보다는 '에러가 발생하지 않았다'는 점이 우선적으로 중요하다. 어떤 변수를 실행하니 undefined가 나왔다는 것은 이 변수가 '호출할 수 있는 함수'에 해당한다는 것을 의미하기 때문이다. 즉, getName이라는 함수가 실제로 실행되었다는 것이 입증되었다.

다음으로, 왜 Suzi라는 값이 나오지 않았는지 살펴보자. 1) this에 원래 의도와는 다른 값이 할당된 것은 아닐까 유추해보고, 2) log/debugger를 찍어보면서 살펴보거나, 3) 지식을 기반으로 문제를 파악해보자.

결론부터 확인하자면, this에 바인딩된 대상이 잘못 지정됐다는 점이 문제이다.

어떤 함수를 '메서드로서' 호출할 때는 메서드명 바로 앞의 객체가 곧 this가 된다. 따라서 thomas.__prototype__.getName()에서 getName 함수 내부의 this는 thomas.__proto__라는 객체가 된다. 이 객체 내부에는 name 프로퍼티가 없기 때문에 undefined가 반환된 것이다.

profile
💡 Software Engineer - F.E

0개의 댓글