본문 바로가기

모던 자바스크립트

8.2 함수의 prototype 프로퍼티

함수의 prototype 프로퍼티

◾️ new F()와 같은 생성자 함수를 이용하면 새로운 객체를 만들 수 있다. 

◾️ F.prototype이 객체면 new 연산자는 F.prototype을 사용해 새롭게 생성된 객체의 [[Prototype]]을 설정한다. 

⚠️ 자바스크립트가 만들어졌을 때는 프로토타입 기반 상속이 주요 기능중 하나였다. 

과거에는 프로토타입에 직접 접근할 방법이 없었다. 생성자 함수의 prototype프로퍼티를 이용하는 방법을 이용했다.  

◾️ F.prototype에서 prototype은 F에 정의된 일반 프로퍼티이다. 프로토타입 객체와는 다르다. 

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 = animalnew Rabbit을 호출해 만든 새로운 객체의 [[Prototype]]을 animal로 설정하라는 것을 의미한다. 

 

◾️ 일반 프로퍼티인 prototype

◾️ [[Prototype]] : rabbit이 animal을 상속 받음

 

 

 

ℹ️ F.prototype은 new F를 호출할 때만 사용된다. 

F.prototype 프로퍼티 new F가 호출할 때만 사용된다. new F를 호출해 새롭게 만든 객체의 [[Prototype]]을 할당해준다. 

로운 객체가 만들어진 후에 F.prototype 프로퍼티가 바뀌면(F.prototype = <another object>) new F로 만들어지는 새로운 객체는 또 따른 객체()를 [[Prototype]]으로 갖게 된다. 다만, 기존에 있던 객체의 [[Prototype]]은 그대로 유지된다. 

 

 

 

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

◾️ 개발자가 특별히 할당하지 않더라도 모든 함수는 prototype 프로퍼티를 갖는다. 

◾️ 기본 프로퍼티인 prototype은 constructor 프로퍼티 하나만 있는 객체를 가리키는데, 이 constructor 프로퍼티는 함수 자신을 가리킨다. 

function Rabbit() {}
  // 기본 prototype
  // Rabbit.prototype = { constructor: Rabbit };

alert( Rabbit.prototype.constructor == Rabbit ); // true

 

◾️ 특별한 조작을 가하지 않았다면 Rabbit을 구현한 객체 모두에서 [[Prototype]]을 거쳐 constructor 프로퍼티를 사용할 수 있다. 

function Rabbit() {}
  // 기본 prototype
  // Rabbit.prototype = { constructor: Rabbit };

let rabbit = new Rabbit(); // { constructor: Rabbit }을 상속받음

alert( rabbit.constructor == Rabbit ); // true (프로토타입을 거쳐 접근)

 

◾️ constructor 프로퍼티를 사용하면 기존에 있던 객체의 constructor를 사용해 새로운 객체를 만들 수 있다. 

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

let rabbit = new Rabbit('White Rabbit');

let rabbit2 = new rabbit.constructor('Black Rabbit');

◾️ 객체가 있는데 이 객체를 만들 때 어떤 생성자가 사용되었는지 알 수 없는 경우(예 : 객체가 서드 파티 라이브러리에서 온 경우), 이 방법을 유용하게 사용할 수 있다. 

◾️ 자바스크립트는 알맞은 constructor 값을 보장하지 않는다. 

◾️ 함수에 기본으로 prototype 값이 설정되긴 하지만 그게 전부이다. constructor에 벌어지는 모든 일은 전적으로 개발자에게 달려 있다. 

 

◾️ 함수의 기본 prototype 값을 다른 객체로 바꾸면 이 객체엔 constructor가 없어진다. 

function Rabbit() {}
Rabbit.prototype = {
  jumps: true
};

let rabbit = new Rabbit();
alert( rabbit.constructor === Rabbit ); // false;

◾️ constructor를 유지하려면 prototype에 원하는 프로퍼티를 추가/제거해야한다. 

function Rabbit() {}
Rabbit.prototype.jumps = true;

let rabbit = new Rabbit();
alert( rabbit.constructor === Rabbit ); // true;

◾️ 또는 constructor 프로퍼티를 수동으로 다시 만들어준다. 

function Rabbit() {}
Rabbit.prototype = {
  jumps: true,
  constructor: Rabbit
}

let rabbit = new Rabbit();
alert( rabbit.constructor === Rabbit ); // true;

 

 

📝 요약

◽️ 생성자 함수를 이용해 만든 객체에 [[Prototype]]을 설정해주는 방법
◽️ F.prototype 프로퍼티는 [[Prototype]]과 다르다. F.prototype은 new F()를 호출할 때 만들어지는 새로운 객체의 [[Prototype]]을 설정한다. 
◽️ F.prototype의 값은 객체나 null만 가능하다. 다른 값은 무시된다. 
◽️ 생성자 함수에 prototype을 설정하고, 이 생성자 함수를 new를 사용해 호출할 때만 적용된다. (일반 객체 X)
◽️ 모든 함수는 기본적으로 F.prototype = { constructor: F }를 가지고 있으므로 함수의 constructor 프로퍼티를 사용하면 객체의 생성자를 얻을 수 있다. 

 

 



📝 오늘 새롭게 배운 내용 📝

 

✅ 과제 - prototype 변경하기

function Rabbit() {}
Rabbit.prototype = {
  eats: true
};

let rabbit = new Rabbit();
alert( rabbit.eats ); // true

 

1️⃣ 

Rabbit.prototype에 무언가를 할당하면 그 값이 새로운 객체의 [[Prototype]]이 된다.

다만 이미 만들어진 객체엔 이 규칙이 적용되지 않는다. 

function Rabbit() {}
Rabbit.prototype = {
  eats: true
};

let rabbit = new Rabbit();

Rabbit.prototype = {};
alert( rabbit.eats ); // true

 

2️⃣

 

객체는 참조에 의해 할당된다.

Rabbit.prototype이 참조하는 객체는 단 하나 뿐인데, 이 객체는 Rabbit.prototype과 rabbit의 [[Prototype]]을 사용해 참조할 수 있다. 따라서 둘 중 하나의 참조를 사용해 객체의 내용을 변경하면 다른 참조를 통해서도 변경 내용을 볼 수 있다.

function Rabbit() {}
Rabbit.prototype = {
  eats: true
};

let rabbit = new Rabbit();

Rabbit.prototype.eats = false;

alert( rabbit.eats ); // false;

 

3️⃣

delete 연산은 객체에 직접 적용된다. 

delete rabbit.eats는 rabbit에서 eats프로퍼티를 제거하는데, rabbit엔 eats가 존재하지 않는다. 

따라서 delete는 아무런 영향을 주지 않는다. 

function Rabbit() {}
Rabbit.prototype = {
  eats: true
};

let rabbit = new Rabbit();
delete rabbit.eats;

alert( rabbit.eats ); // true;

 

4️⃣

프로퍼티 eats가 프로토타입에서 삭제 되었기 때문에 eats는 더이상 존재하지 않는다. 

function Rabbit() {}
Rabbit.prototype = {
  eats: true
};

let rabbit = new Rabbit();

delete Rabbit.prototype.eats;

alert( rabbit.eats ); // undefined

 

어렵다... ; ;;; 

 

 

 

📌 [JAVASCRIPT_INFO 함수의 prototype 프로퍼티]

 

함수의 prototype 프로퍼티

 

ko.javascript.info

 

📌 [MDN Object.prototype]

 

Object.prototype

Object.prototype 속성은 Object 프로토타입(원형) 객체를 나타냅니다.

developer.mozilla.org