자바스크립트에서 __proto__ VS. prototype 비교
__proto__
는 메서드 등을 체인을 타고 찾는데 사용되는 실제 객체이다.prototype
은new
로 인스턴스를 만들 때__proto__
를 생성하는 데 사용하는 객체다.
function Foo() {}
console.log(new Foo().__proto__ === Foo.prototype); // true, 인스턴스의 __proto__와 함수의 prototype은 같다
console.log(new Foo().prototype === Foo.prototype); // false, 인스턴스의 prototype과 함수의 prototype은 다르다.
console.log(new Foo().prototype === undefined); // true, 인스턴스의 prototype은 undefined이다(즉, 없다?).
console.log(new Foo() instanceof Foo); // true
console.log(new Foo() instanceof Object); // true
console.log(new Foo().__proto__.__proto__ === Object.prototype); // true
console.log(Foo.__proto__ === Function.prototype); // true
console.log(new Foo().__proto__); // Foo.prototype과 동일하다
/* {constructor: ƒ}
constructor: ƒ Foo
[[Prototype]]: Object */
console.log(Foo.prototype.constructor); // Foo, 함수 정의 반환
console.log(Foo.prototype.__proto__); // {}, 빈 객체 반환, 함수이므로 root level인 Object.prototype을 가리킨다
- 함수 정의 코드를 실행하면, 자바스크립트는 해당 함수에
prototype
프로퍼티를 추가한다. 해당prototype
프로퍼티는constructor
와__proto__
라는 두 개의 프로퍼티를 가진 객체다.
- 브라우저에서 콘솔로 찍으면__proto__
는 안 보이고,[[Prototype]]
만 보여서 이건 또 뭐냐고 물을 수 있다. 사실 둘은 같은 것이다. 정확히 말하면,__proto__
는[[Prototype]]
에 대하여 브라우저에서 지원하는 getter이다.[[Prototype]]
은 private 연결이므로 직접적으로 접근할 수 없다. prototype
프로퍼티는 인스턴스 내에서 사용할 수는 없고, 함수에서만 사용할 수 있다.- 대신, 인스턴스는
__proto__
프로퍼티를 통해 함수의prototype
프로퍼티를 참조한다. - 그리고 함수
__proto__
프로퍼티는 더 상위의 Function의prototype
프로퍼티를 참조한다. 따라서 서로 다른 함수의__proto__
프로퍼티들을 비교하면 같음을 확인할 수 있다. - 즉,
prototype
프로퍼티는 저장되는 실제 객체인__proto__
프로퍼티를 위한 청사진일뿐이다. 다른 말로 풀자면,prototype
은 생성자 함수(constructor functions)에서 사용되는 것이며, 이러한 정의를 담는 정확한 용어로"prototypeToInstall"
로 했어야 오해가 없었을 것이다. - 반면,
__proto__
의 정의에 잘 맞는 용어는"installedPrototype"
으로 했어야 이해하기 쉬웠을 것이다.
정리해서, 함수를 new
키워드를 사용하여 인스턴스를 만들면 다음과 같은 일이 발생한다.
function SetName(name) {
this.name = name;
}
const marco = new SetName("Marco");
- 빈 새 객체를 만든다.
- marco에
__proto__
프로퍼티를 만들고, 그__proto__
프로퍼티가 SetName의prototype
을 가리키게 한다. - 1번에서 만든 새 객체의 context(this)로
SetName.prototype.constructor
(= SetName 함수정의)가 실행(execute)되며, 이러한 해당 함수정의에 따라 "Marco" 문자열을 전달받은 'name' 프로퍼티가 새 객체에 추가된다. - const
marco
에 해당 새 객체(1번에서 만들어진)가 지정되어 반환된다..
- 결론 : 인스턴스는
__proto__
프로퍼티만을 제대로 갖고, 클래스와 생성자함수는 추가로prototype
프로퍼티를 갖는다. 인스턴스의__proto__
프로퍼티는 클래스나 생성자함수의prototype
을 가리킨다. (사족을 덧붙이자면, 클래스와 생성자함수의__proto__
프로퍼티는 root level의Function.prototype
프로퍼티를 가리킨다.
추가로 Function과 Object의 프로토타입 관계를 아담과 이브
에 빗대어 살펴보자.(SOF - __proto__
VS. constructor.prototype
)
Object
는 이브이고, Function
은 아담이다. 아담(Function
)은 그의 갈비뼈(Function.prototype
)을 사용하여 이브(Object
)를 창조하였다. 그러면 아담(Function
)은 누가 창조했는가? - 자바스크립트 언어를 만든 사람! -
따라서 아래와 같은 비교 결과가 모두 참이 된다.
console.log(Object.__proto__ === Function.prototype); // true
console.log(Function.prototype === Function.__proto__); // true, 그 위는 없다.
console.log(Object.__proto__ === Foo.__proto__); // true, 둘 다 Function.prototype을 참조한다.
예제
class Foo {
hello() {return '안녕하세요'}
}
class Bar extends Foo{
#age;
constructor(){
super();
this.name = "마르코";
this.#age = 11;
}
getName(){return this.name + " 입니다"}
get age(){return this.#age }
static bye() {return '잘가요'}
}
const bar = new Bar();
console.dir(Foo);
console.dir(Bar);
console.dir(new Foo());
console.dir(new Bar());
콘솔결과
Author And Source
이 문제에 관하여(자바스크립트에서 __proto__ VS. prototype 비교), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jangws/자바스크립트에서-proto-VS.-prototype-비교저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)