프로토타입이란
프로토타입은 객체의 원형이다. 자바스크립트의 모든 객체는 프로토타입 객체를 가지며, 이를 통해 메소드와 속성을 상속받는다.
console.dir()로 객체를 출력해보면 [[Prototype]]이라는 숨겨진 속성을 확인할 수 있는데, 이게 바로 자신의 부모 객체를 가리키는 참조다.
[[Prototype]]자바스크립트 엔진 내부에서 관리하는 슬롯으로, 개발자가 직접 접근할 수 없다.
직접 접근을 막는 이유는 프로토타입 체인이 항상 단방향(자식 → 부모)을 유지하게 하고, 순환참조 같은 실수를 방지하기 위해서다.
__proto__[[Prototype]]에 간접적으로 접근하기 위한 프로퍼티다. Object.getPrototypeOf()와 동일하게 동작한다.
function Person(name) {
this.name = name;
}
console.log(Person.__proto__ === Object.getPrototypeOf(Person)); // true
생성자 함수만 가지는 프로퍼티다. new로 객체를 생성했을 때, 그 객체의 [[Prototype]]이 생성자 함수의 prototype을 가리키게 된다.
function Person(name) {
this.name = name;
}
const foo = new Person('코드잇');
console.log(foo.__proto__ === Person.prototype); // true
일반 객체와 화살표 함수는 prototype 프로퍼티가 없다.
객체에서 특정 프로퍼티나 메소드를 찾을 때, 없으면 부모 프로토타입을 타고 올라가며 검색한다. 이 연결 구조를 프로토타입 체인이라고 한다.
const foo = new Person('코드잇');
const arr = [1, 2, 3];
console.log(foo.__proto__ === Person.prototype); // true
console.log(foo.__proto__.__proto__ === Object.prototype); // true
console.log(arr.__proto__ === Array.prototype); // true
console.log(arr.__proto__.__proto__ === Object.prototype); // true
체인을 계속 타고 올라가면 결국 Object.prototype에 도달한다. 여기에 toString(), hasOwnProperty() 같이 모든 객체에서 쓸 수 있는 메소드들이 정의되어 있다.
foo → Person.prototype → Object.prototype → null
arr → Array.prototype → Object.prototype → null