함수의 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 = animal은 new 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 프로퍼티]
📌 [MDN Object.prototype]
'모던 자바스크립트' 카테고리의 다른 글
8.4 프로토타입 메서드와 __proto__가 없는 객체 (0) | 2020.09.23 |
---|---|
8.3 네이티브 프로토타입 (0) | 2020.09.17 |
8.1 프로토타입 상속 (0) | 2020.09.09 |
6.10 화살표 함수 다시 살펴보기 (0) | 2020.09.02 |
6.10 함수 바인딩 (0) | 2020.09.01 |