프로토타입은 자바스크립트에서 객체를 상속하기 위해 사용하는 방식이다.
프로토타입은 객체가 연쇄적으로 상속할 수 있게 한다.
자바스크립트는 프로토타입 기반 언어(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__의 차이를 잘 정리핸준 블로그이다.