2014년 3월 24일 월요일

Javascript, prototype, [[Prototype]]

자바스크립트에는 프로토타입이라는 특이한 요소가 있다.
이 프로토타입이 혼동스러운 가장 큰 이유는 우리말로는 프로토타입 하나지만,
실제 자바스크립트에는 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

댓글 없음:

댓글 쓰기