자바스크립트에는 프로토타입이라는 특이한 요소가 있다.
이 프로토타입이 혼동스러운 가장 큰 이유는 우리말로는 프로토타입 하나지만,
실제 자바스크립트에는 prototype과 [[Prototype]] 두 개가 존재하기 때문이다.
주변에 접할 수 있는 책에서 '프로토타입 객체'라고 하면 prototype을 말하는 것일까 아니면 [[Prototype]]을 말하는 것일까?
솔직히 내가 읽은 여러권의 책으로는 그때그때 달랐다.. 이다. ㅠㅜ
그래서 한 번 명확하게 정리 해봤다.
함수 객체에만 존재하는 prototype 객체와 모든 객체에 존재하는 [[Prorotype]] 객체로 나누어 기술한다.
정리하다가 특이한 점을 하나 더 발견했는데, prototype 객체의 constructor는 실제 그 prototype 객체를 생성한 함수가 아니라는 점이다!!!!
---------------------
- new를 통해 생성된 객체는 [[Prototype]] 객체를 가진다.
- new를 통해 생성된 객체의 [[Prototype]] 객체는 생성자 함수의 prototype 객체다.
- 모든 객체는 new를 통해 생성된다.(리터럴을 쓰더라도 내부적으로는 new를 통해 생성)
- 따라서 모든 객체의 [[Prototype]] 객체는 생성자 함수의 prototype 객체다.
- 모든 함수 객체의 constructor는 Function 객체다.
- 모든 함수 객체만 prototype 객체를 가진다.
- 함수 객체도 객체다.
- 따라서 함수 객체는 prototype 객체와 [[Prototype]] 객체를 모두 가진다.
- prototype 객체는 constructor와 [[Prototype]]라는 property만을 가지고 있는 객체로서, 함수 객체가 아니다.
- 따라서 일반적인 함수 객체의 prototype 객체와 [[Prototype]] 객체는 당연히 다르다.
- 다만 Function 객체만 예외적으로 prototype 객체와 [[Prototype]] 객체가 같다.
- 일반적인 객체의 constructor는 그 객체를 생성하는데 사용된 생성자 함수 객체다.
- prototype 객체는 실제로 Object 함수에 의해 생성되지만, prototype 객체의 constructor는 Object 함수가 아니라, 그 prototype 객체를 'prototype'이라는 이름의 property로 가지고 있는 함수 객체다.
- 따라서 prototype 객체의 [[Prototype]]은 constructor의 prototype 객체가 아니라 실제 prototype 객체를 생성한 Object 함수의 prototype 객체다.
- 이름 있는 함수의 prototype 객체는 그 함수의 이름으로 표시되지만, 그 함수 객체와는 다른 객체다.
- 이름 없는 함수의 prototype 객체는 Object라는 이름으로 표시되지만, 일반적으로 말하는 Object 객체와는 다른 객체다.
아래의 값은 모두 참이다.
[[Prototype]]는 표기법이며, 브라우저에 따라 예약어가 다르다.
크롬이나 파이어폭스에서는 [[Prototype]] 대신 __proto__라고 쓰면 된다.
- var obj = {}, func = function func() {};
- obj.[[Prototype]] === obj.constructor.prototype
- func.prototype.[[Prototype]] !== func.prototype.constructor.prototype // <- prototype 객체의 constructor와 실제 prototype을 생성하는데 사용된 생성자 함수가 다르다!!
- func.prototype !=== func.[[Prototype]]
- Function.prototype.constructor === Function
- Function.[[Prototype]].constructor === Function
- Function.prototype === Function.[[Prototype]]
- Function.constructor === Function
- Function instanceof Object
- Object instanceof Function
- Object.prototype.constructor === Object