프로토타입은 자바스크립트에서 객체를 상속하기 위해 사용하는 방식이다.
프로토타입은 객체가 연쇄적으로 상속할 수 있게 한다.
자바스크립트는 프로토타입 기반 언어(prototype-based language)라 불린다.
프로토타입 속성은 상속받은 멤버들이 정의된 곳이다.
mdn에서 Array 객체의 pop() 메서드 문서를 확인하면,
Array.pop()이 아니라, Array.prototype.pop()으로 작성되어있다.
이는 pop() 메서드가 .prototype에 정의되어있기 때문이다.
__proto__는 Prototype 속성에서 파생된 속성이다.
"Object.prototype의 __proto__ 속성은 접근하고자 하는 객체의 내부 속성인 [[Prototype]](객체 또는 null)를 노출하는 접근자 속성(getter 및 setter 함수)입니다."
- mdn Object.prototype.__proto__
"JavaScript에서는 객체 인스턴스와 프로토타입 간에 연결(많은 브라우저들이 생성자의 prototype 속성에서 파생된 __proto__ 속성으로 객체 인스턴스에 구현하고 있습니다.)이 구성되며 이 연결을 따라 프로토타입 체인을 타고 올라가며 속성과 메소드를 탐색합니다."
- mdn Object prototypes
예시로 이를 확인할 수 있다.
class Lunch { constructor(food) { this.food = food; } eat() { console.log("let's eat " + this.food + "!"); } } class Brunch extends Lunch { constructor(food) { super(food); this.state = 'starving'; } say() { console.log("I'm " + this.state + "..."); } }
예를 들어 food 속성과 constructor, eat 메서드를 가진 Lunch 클래스가 있고,
Lunch 클래스를 상속받은 Brunch 클래스가 있다고 가정하자.
console.log(Lunch.prototype);
Lunch.prototype에 Lunch의 constructor, eat 메서드와 [[Prototype]]이 정의되어있다.
[[Prototype]]에는 상속받은 Object 클래스의 메서드들이 정의되어있다.
console.log(Brunch.prototype);
Brunch.prototype에는 Brunch의 constructor, say 메서드와 [[Prototype]]이 정의되어있다.
[[Prototype]]에는 상속받은 Lunch의 메서드들이 정의되어있다.
const nth2eat = new Lunch('cookie'); console.log(nth2eat.__proto__);
Lunch의 인스턴스인 nth2eat을 생성했다.
인스턴스의 prototype에 접근하기 위해서는 __proto__ 속성을 이용한다.
nth2eat.__proto__에도 cunstructor, eat 메서드와 [[Prototype]]이 정의되어있다.
앞서 말한대로 __proto__ 속성으로 접근하고자 하는 객체의 내부 속성인 [[Prototype]]에 접근할 수 있음을 확인했다.
prototype과 __proto__의 차이를 잘 정리핸준 블로그이다.