프로토타입 체인은 자바스크립트가 객체지향 프로그래밍의 상속을 구현하는 메커니즘이다. 자바스크립트는 객체의 프로퍼티(메서드 포함)에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없다면 [[Prototype]] 내부 슬롯의 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다.
①function Person(name) {
this.name = name;
}
②Person.prototype.sayHello = function () {
console.log(`Hi! My name is ${this.name}`);
};
③const me = new Person("Lee");
console.log(Object.getPrototypeOf(me) === Person.prototype); // true
console.log(Object.getPrototypeOf(Person.prototype) === Object.prototype); // true
메서드를 검색하는 과정 (프로퍼티를 참조하는 경우도 동일)
me.hasOwnProperty("name"); // true
hasOwnProperty 메서드를 호출한 me 객체에서 hasOwnProperty 메서드를 검색한다. me 객체에는 hasOwnProperty 메서드가 없으므로 프로토타입 체인을 따라, [[Prototype]] 내부 슬롯에 바인딩되어 있는 프로토타입으로 이동하여 hasOwnProperty 메서드를 검색한다.
Person.prototype에도 hasOwnProperty 메서드가 없으므로 프로토타입 체인을 따라, [[Prototype]] 내부 슬롯에 바인딩되어 있는 프로토타입으로 이동하여 hasOwnProperty 메서드를 검색한다.
Object.prototype에는 hasOwnProperty 메서드가 존재한다. 자바스크립트 엔진은 Object.prototype.hasOwnProperty 메서드를 호출한다. 이때 메서드의 this에는 me 객체가 바인딩된다.
Object.prototype.hasOwnProperty.call(me, 'name');
Object.prototype: 프로토타입 체인의 종점(end of prototype chain)
프로토타입 체인의 최상위에 위치하는 객체는 언제나 Object.prototype이다. 따라서 모든 객체는 Object.prototype을 상속받는다. Object.prototype의 프로토타입, 즉 [[Prototype]] 내부 슬롯의 값은 null이다. Object.prototype에서도 프로퍼티를 검색할 수 없는 경우 undefined를 반환한다. ⚠️ 이때 에러가 발생하지 않는다.
me.foo; // undefined
프로토타입 체인과 스코프 체인
스코프 체인과 프로토타입 체인은 서로 협력하여 식별자와 프로퍼티를 검색하는데 사용된다.
프로토타입 체인 | 스코프 체인 |
---|---|
상속과 프로퍼티 검색을 위한 메커니즘 | 식별자 검색을 위한 메커니즘 |
자바스크립트 엔진은 객체 간의 상속 관계로 이루어진 프로토타입의 계층적인 구조에서 객체의 프로퍼티를 검색한다. | 자바스크립트 엔진은 함수의 중첩 관계로 이루어진 스코프의 계층적 구조에서 식별자를 검색한다. |
⇒ 프로퍼티와 메서드는 프로토타입 체인에서 검색한다. | ⇒ 식별자는 스코프 체인에서 검색한다. |