자바스크립트의 객체는 명세서에서 명명한 [[prototype]] 이라는 내부 프로퍼티이자 숨김 프로퍼티
를 갖는다. 이 숨김 프로퍼티의 값은 null이거나 다른 객체에 대한 참조가 되는데, 다른 객체를 참조하는 경우 참조 대상을 prototype
이라 부른다.
let animal = {
eats: true
}
let rabbit = {
jumps: true
}
rabbit.__proto__ = animal
위의 코드를 보면 rabbit 에 __proto__
를 사용하여 animal 객체를 rabbit의 프로토타입으로 설정해주고 있다.
prototype은 생성자 함수 내부에 있는 프로퍼티 또는 메소드를 가지고 있는 새로운 여러 객체를 생성하여 사용하고자 할 때 유용하다.
console.log(rabbit.eats); //true
위에서 설명한 코드에 추가해 rabbit 객체에서 eats 프로퍼티를 불렀더니 true의 결과가 나왔다. 이는 rabbit 이 animal 객체를 프로토타입으로 설정하여 animal 내부의 프로퍼티 및 메소드를 rabbit 에서도 animal 객체를 참조하여 똑같이 사용할 수 있게 되었다는 것을 보여준다.
__proto__는 [[Prototype]]의 getter(획득자)이자 setter(설정자)로 아마 객체의 프로토타입을 설정하거나 변경하거나 읽을 때 필요한 것이 __proto__이고, [[Prototype]]은 프로토타입을 의미하는 것 같다 .. (이 부분은 확실치 않으므로 확인하도록 한다.)
하지만 이 마저도 현재는 잘 사용되지 않는다고 한다.
- 순환 참조(circular reference)는 허용되지 않는다. __proto__ 를 이용해 닫히 형태로 다른 객체를 참조하면 에러 발생한다.
- _proto__ 의 값은 객체나 null만 가능하다. 다른 자료형은 무시된다.
- 객체엔 오직 하나의 [[Prototype]]만 있을 수 있다. 객체는 두 개의 객체를 상속받지 못한다.
for..in
for in의 경우 객체 자신의 키와 상속 프로퍼티의 키 모두를 순회한다. 다만, 기본 객체가 참조하는 Object.prototype 의 키는 열거 가능한(enumerable)이 아니기 때문에 순회 대상에 포함되지 않는다.
hasOwnProperty
객체 자신의 프로퍼티의 경우 true를, 상속 프로퍼티의 경우 false 를 리턴해 다른 프로퍼티를 구별할 수 있다.
키-값을 순회하는 메서드
대부분은 상속 프로퍼티를 제외하고 해당 객체에서 정의한 프로퍼티만 연산 대상에 포함시킨다.