웹공부/JS

프로토타입 - 상속

syom 2021. 10. 13. 09:01

https://ko.javascript.info/prototype-inheritance

프로토타입 (prototype)

자바스크립트의 객체는 명세서에서 명명한 [[prototype]] 이라는 숨김 프로퍼티를 갖는다.
이 숨김 프로퍼티 값은 null 이거나 다른 객체에 대한 참조가 되는데,
다른 객체를 참조하는 경우 참조 대상을 '프로토타입(prototype)'이라 부른다.

프로토타입 설정

let animal = {
  eats: true
};
let rabbit = {
  jumps: true
};

rabbit.__proto__ = animal;

이런식으로 개발자가 직접 값을 설정할 수 있다.

❗️ __proto__는 [[Prototype]]용 getter·setter입니다.

__proto__는 [[Prototype]]과 다릅니다. __proto__는 [[Prototype]]의 getter(획득자)이자 setter(설정자) 입니다.

하위 호환성 때문에 여전히 __proto__를 사용할 순 있지만 비교적 근래에 작성된 스크립트에선 __proto__ 대신 함수 Object.getPrototypeOf나 Object.setPrototypeOf을 써서 프로토타입을 획득(get)하거나 설정(set)합니다. 근래엔 왜 __proto__를 쓰지 않는지와 두 함수의 자세한 설명에 대해선 이어지는 챕터에서 다룰 예정입니다.

__proto__는 브라우저 환경에서만 지원하도록 자바스크립트 명세서에서 규정하였는데, 실상은 서버 사이드를 포함한 모든 호스트 환경에서 __proto__를 지원합니다. [[Prototype]]보다는 __proto__가 조금 더 직관적이어서 이해하기 쉬우므로, 본 튜토리얼의 예시에선 __proto__를 사용하도록 하겠습니다.

for ... in 반복문

for ... in 은 상속 프로퍼티도 순회 대상에 포함된다.
obj.hasOwnProperty(key)를 이용하면 상속 프로퍼티를 순회 대상에서 제외할 수 있다.
이 내장 메서드는 key에 대응하는 프로퍼티가 상속 프로퍼티가 아니고 obj에 직접 구현되어있는 프로퍼티일 때 true를 반환한다.

let animal = {
  eats: true
};

let rabbit = {
  jumps: true,
  __proto__: animal
};

for(let prop in rabbit) {
  let isOwn = rabbit.hasOwnProperty(prop);

  if (isOwn) {
    alert(`객체 자신의 프로퍼티: ${prop}`); // 객체 자신의 프로퍼티: jumps
  } else {
    alert(`상속 프로퍼티: ${prop}`); // 상속 프로퍼티: eats
  }
}