본문 바로가기

자바스크립트

포로토타입과 프로토타입 상속

프로토타입 상속

[[Prototype]]

자바스크립트의 객체는 명세서에서 명명한 [[Prototype]] 이라는 숨김 프로퍼티를 갖습니다.

이 숨김 프로퍼티 값은 null이거나 다른 객체에 대한 참조가 되는데, 다른 객체를 참조하는 경우 참조 대상을 프로토타입이라 부릅니다.

object에서 프로퍼티를 읽으려고 하는데 해당 프로퍼티가 없으면 자바 스크립트는 자동으로 프로토타입에서 프로퍼티를 찾음. -> 프로토타입 상속

let animal = {
 eats: 프로토타입과 프로토타입 상속

프로토타입 상속

[[Prototype]]

자바스크립트의 객체는 명세서에서 명명한 [[Prototype]] 이라는 숨김 프로퍼티를 갖습니다.

이 숨김 프로퍼티 값은 null이거나 다른 객체에 대한 참조가 되는데, 다른 객체를 참조하는 경우 참조 대상을 프로토타입이라 부릅니다.

object에서 프로퍼티를 읽으려고 하는데 해당 프로퍼티가 없으면 자바 스크립트는 자동으로 프로토타입에서 프로퍼티를 찾음. -> 프로토타입 상속

let animal = {
  eats: true
};

let rabbit = {
  jumps: true
};

rabbit.__proto__ = animal;

alert(rabbit.eats); // rabbit.eats 프로퍼티를 읽으려 했는데 없으면 [[Prototype]] 이 참조하고 있는 객체인 animal에서 찾음.

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

프로토 타입 체이닝 제약사항

  1. 순환 참조는 허용되지 않음.
  2. __proto__의 값은 객체나 null만 가능.
  • this는 프로토타입에 영향을 받지 않음.
  • 메서드를 객체에서 호출했든 프로토타입에서 호출했든 상관없이 this는 언제나 .앞에 있는 객체.
let animal = {
  eats: true
};

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

// Object.keys는 객체 자신의 키만 반환합니다.
alert(Object.keys(rabbit)); // jumps

// for..in은 객체 자신의 키와 상속 프로퍼티의 키 모두를 순회합니다.
for(let prop in rabbit) alert(prop); // jumps, eats

함수의 prototype 프로퍼티

let animal = {
  eats: true
};

function Rabbit(name) {
  this.name = name;
}

Rabbit.prototype = animal;

let rabbit = new Rabbit("White Rabbit"); //  rabbit.__proto__ == animal

alert( rabbit.eats ); // true

Rabbit.prototype = animal은 "new Rabbit을 호출해 만든 새로운 객체의 [[Prototype]]animal로 설정

함수의 prototype 프로퍼티와 constructor 프로퍼티

개발자가 특별히 할당하지 않아도 모든 함수는 "prototype" 갖음

기본 프로퍼티인 "prototype"은 constructor 프로퍼티 하나만 있는 객체를 가리킴. 함수 자기 자신을 가리킴.

function Rabbit() {}

/* 기본 prototype
Rabbit.prototype = { constructor: Rabbit };
*/

네이티브 프로토타입

let obj = {}; // == let obj == new Object();
console.log(obj); // [object Object]
let arr = [1, 2, 3];

console.log(arr.__proto__ === Array.prototype); // true
console.log(arr.__proto__.__proto__ === Object.prototype); // true
console.log(arr.__proto__.__proto__.__proto__ === null); // true

네이티브 프로토타입을 수정할 수 있음 -> 이는 좋은 방법이 아님. 프로토 타입은 전역으로 영향을 미치지 때문에 프로토 타입을 조작하면 충돌이 날 가능성이 있음.

모던 프로그래밍에서 네이티브 프로토타입 변경을 허용하는 경우는 딱 하나 -> 폴리필을 만들 때

폴리필 : 자바스크립트 명세서에 있는 메서드와 동일한 기능을 하는 메서드 구현체를 의미. 명세서에는 정의되어 있으나 특정 자바스크립트 엔진에서는 해당 기능이 구현되어있지 않을 때 폴리필을 사용.

프로토타입에서 빌려오기

let obj = {
  0:  "Hello",
  1: "world",
  length: 2,
};

obj.join = Array.prototype.join;
alert(obj.join(","));

유사 배열 객체를 만들고 여기에 Array 메서드를 복사


프로토타입 메서드와 proto 가 없는 객체

 

true
};

let rabbit = {
 jumps: true
};

rabbit.__proto__ = animal;

alert(rabbit.eats); // rabbit.eats 프로퍼티를 읽으려 했는데 없으면 [[Prototype]] 이 참조하고 있는 객체인 animal에서 찾음.let animal = {
 eats: true
};

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

// Object.keys는 객체 자신의 키만 반환합니다.
alert(Object.keys(rabbit)); // jumps

// for..in은 객체 자신의 키와 상속 프로퍼티의 키 모두를 순회합니다.
for(let prop in rabbit) alert(prop); // jumps, eatslet animal = {
 eats: true
};

function Rabbit(name) {
 this.name = name;
}

Rabbit.prototype = animal;

let rabbit = new Rabbit("White Rabbit"); // rabbit.__proto__ == animal

alert( rabbit.eats ); // truefunction Rabbit() {}

/* 기본 prototype
Rabbit.prototype = { constructor: Rabbit };
*/let obj = {}; // == let obj == new Object();
console.log(obj); // [object Object]let arr = [1, 2, 3];

console.log(arr.__proto__ === Array.prototype); // true
console.log(arr.__proto__.__proto__ === Object.prototype); // true
console.log(arr.__proto__.__proto__.__proto__ === null); // true
let obj = {
 0:  "Hello",
 1: "world",
 length: 2,
};

obj.join = Array.prototype.join;
alert(obj.join(","));

프로토타입 메서드와 proto 가 없는 객체


유사 배열 객체를 만들고 여기에 Array 메서드를 복사

프로토타입에서 빌려오기

폴리필 : 자바스크립트 명세서에 있는 메서드와 동일한 기능을 하는 메서드 구현체를 의미. 명세서에는 정의되어 있으나 특정 자바스크립트 엔진에서는 해당 기능이 구현되어있지 않을 때 폴리필을 사용.

모던 프로그래밍에서 네이티브 프로토타입 변경을 허용하는 경우는 딱 하나 -> 폴리필을 만들 때

네이티브 프로토타입을 수정할 수 있음 -> 이는 좋은 방법이 아님. 프로토 타입은 전역으로 영향을 미치지 때문에 프로토 타입을 조작하면 충돌이 날 가능성이 있음.

네이티브 프로토타입


기본 프로퍼티인 "prototype"은 constructor 프로퍼티 하나만 있는 객체를 가리킴. 함수 자기 자신을 가리킴.

개발자가 특별히 할당하지 않아도 모든 함수는 "prototype" 갖음

함수의 prototype 프로퍼티와 constructor 프로퍼티

Rabbit.prototype = animal은 "new Rabbit을 호출해 만든 새로운 객체의 [[Prototype]]animal로 설정

함수의 prototype 프로퍼티


  • this는 프로토타입에 영향을 받지 않음.

  • 메서드를 객체에서 호출했든 프로토타입에서 호출했든 상관없이 this는 언제나 .앞에 있는 객체.

  1. 순환 참조는 허용되지 않음.

  2. __proto__의 값은 객체나 null만 가능.

프로토 타입 체이닝 제약사항

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