본문 바로가기
[JavaScript]

[javascript] prototype과 __proto__

by 쥰5017 2022. 10. 3.

 

Prototype이란?

생성자 함수 Object는 내장 객체 생성자 함수인데, 이 생성자 함수의 prototype은 다양한 프로퍼티나 메서드가 구현되어 있는 객체를 참조한다.

 

이 Object 생성자 함수로 만들어진 객체는 [[Prototype]]이라는 숨김 프로퍼티를 갖는다. 이 숨김 프로퍼티 값은 null이거나 다른 객체에 대한 참조가 되는데, 다른 객체를 참조하는 경우 참조 대상을 프로토타입 객체 또는 프로토타입이라고 부른다. 일반적으로 부모 객체를 참조하게 되며 프로퍼티 또는 메서드를 상속받는다고 표현한다. 

 

obj의 프로퍼티나 메서드에 접근하려고 할 때, obj에 접근하려는 프로퍼티나 메서드가 없다면 [[Prototype]]이 가리키는 링크를 따라 자신의 부모 역할을 하는 Object의 프로퍼티나 메서드를 찾는다. 이것을 프로토타입 체인이라고 한다. 이때 obj가 부모 객체인 Object를 참조할 수 있다고 해서 자식 객체가 부모의 프로퍼티나 메서드를 직접 갖는 것은 아니다. 아래의 예를 보면

let obj = {};

alert(obj.prototype === Object.prototype); // false
alert(obj.toString === Object.prototype.toString); //true

obj의 프로토타입과 Object의 프로토타입은 같지 않다고 나오는데, toString 메서드는 같다고 나온다. 이는 애초에 obj.toString이 obj가 갖고 있는 것이 아닌 Object에서 참조해 온 것이기 때문이다.

 

 

 

__proto__란?

기본적으로는 __proto__는 부모 객체의 프로토타입을 가리키는 프로퍼티이다. 그렇기에 [[prototype]]용 getter와 setter라고 할 수 있다. 

//예제 1
let obj = {};

alert(obj.__proto__ === Object.prototype); // true
alert(obj.toString === obj.__proto__.toString); //true

//예제 2
let animal = {
  eats: true
};
let rabbit = {
  jumps: true
};

rabbit.__proto__ = animal; 

// 프로퍼티 eats과 jumps를 rabbit에서도 사용할 수 있게 되었습니다.
// rabbit이 animal을 상속받는다.
alert( rabbit.eats ); // true
alert( rabbit.jumps ); // true

MDN에 나온 바로는 __proto__를 사용해 프로토타입을 변경하지 말라고 경고한다. 코드 전체에 광범위하게 영향을 줄 수 있기 때문이다. (프로토타입 체인을 잘못 건드리게 될 수 있으므로)

 

 

 

+다양한 내장 객체의 프로토타입

 

 

 

 

 

 

댓글