: 자바스크립트는 프로토타입 기반 언어이다. 모든 객체들이 클래스로 정의해놓은 메소드와 속성을 상속받기 위한 템플릿으로써 프로토타입 객체를 가진다.
Prototype
: 모든 객체들이 클래스의 정보들을 상속받을 수 있도록 템플릿 역할을 수행한다.
기본적으로 Class로 객체를 정의한다고 해도 자바스크립트 내부적으로는 프로토타입으로 관리된다.
ES2015 클래스 구문으로 조금더 편리하게 볼 수 있도록 제공하는것
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
class Person { constructor(name, age) { this.name = name; this.age = age; } getName() { return this.name; } } // ---------------------- 위의 방식으로 class를 선언한다고해도 사실은 아래와같이 관리됨 function Person(name, age) { this.name = name; this.age = age; } Person.prototype.getName = function() { return this.name; }
함수의 prototype 프로퍼티와 프로토타입 객체의 constructor 프로퍼티
1
2
3
4
5
6
7
function Rabbit(name) {
this.name = name;
}
// 기본 prototype
// Rabbit.prototype = { constructor: Rabbit };
let rabbit = new Rabbit("white rabbit");
- 위와같은 줄을 그림으로 표현하면 아래와 같다.

Rabbit 함수에서는
Rabbit.prototype과 같이 Rabbit 프로토타입 객체로 접근 가능Rabbit 프로토타입 객체에서는 constructur 속성은 Rabbit 함수를 참조한다.
getName(),setName()같은 프로퍼티들이 Rabbit 함수에 추가가 되면 프로토타입에 해당 프로퍼티를 유지한다.- 따라서, 새로 만든 인스턴스들은 프로토타입 원형을 복사해 사용한다.
1 2 3 4 5 6 7 8
function Rabbit(name) { this.name = name; alert(name); } let rabbit = new Rabbit("White Rabbit"); let rabbit2 = new rabbit.constructor("Black Rabbit");
- 위와같은 경우 rabbit 객체의 constructor로 Rabbit 함수에 접근하는 것
자바스크립트는 알맞은 constructor 값을 보장하지 않는다.
1
2
3
4
5
6
7
function Rabbit() {}
Rabbit.prototype = {
jumps: true
};
let rabbit = new Rabbit();
alert(rabbit.constructor === Rabbit); // false
- 위처럼 기본
prototype값을 다른 객체로 바꾸면 이 객체에는 contructor가 없을 것..
깊이 이해하기
- 아래와같은 코드를 베이스로 변경하는 경우의 시나리오를 알아보기
1
2
3
4
5
6
7
8
function Rabbit() {}
Rabbit.prototype = {
eats: true
};
let rabbit = new Rabbit();
alert( rabbit.eats ); // true
이미 만들어진 객체에 대해서는 영향을 주지 않는다 .
1
2
3
4
5
6
7
8
9
10
function Rabbit() {}
Rabbit.prototype = {
eats: true
};
let rabbit = new Rabbit();
Rabbit.prototype = {}; // add this line
alert( rabbit.eats ); // true
Rabbit.prototype이 참조하는 객체는 하나뿐이기 때문에 참조를 통해 객체 내용을 변경하면 다른 참조를 통해서도 변경 내용을 볼 수 있다.
1
2
3
4
5
6
7
8
9
10
function Rabbit() {}
Rabbit.prototype = {
eats: true
};
let rabbit = new Rabbit();
Rabbit.prototype.eats = false; // add this line
alert( rabbit.eats ); // false
객체의 프로퍼티를 제거해도 따로 변화가 없다. 그러나, 객체가 참조하는 prototype 객체를 변경하면 달라진다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Rabbit() {}
Rabbit.prototype = {
eats: true
};
let rabbit = new Rabbit();
delete rabbit.eats;
alert( rabbit.eats ); // true
delete Rabbit.prototype.eats;
alert( rabbit.eats ); // undefined
- 만약 rabbit에서 eats를 재정의해서 사용하고 있고, 그 때
rabbit.eats를 건드리면 그 객체의 프로퍼티가 변경 될 것
시나리오로 이해하기
1
2
3
4
5
6
7
8
9
function User(name) {
this.name = name;
}
User.prototype = {}; // (*)
let user = new User('John');
let user2 = new user.constructor('Pete');
alert( user2.name ); // undefined
new user.constructor('Pete')는user에서constructor를 찾는데 아무것도 찾지 못한다.- 객체에서 원하는 프로퍼티를 찾지 못했기 때문에 프로토타입 객체에서 검색을 한다.
user의 프로토타입은User.prototype인데,User.prototype은 빈 객체이다. User.prototype은 일반 객체{}이고, 일반 객체의 프로토타입은Object.prototype이다.Object.prototype.constructor == Object이므로Object가 사용된다.
Reference)
모던 JavaScript 튜토리얼 https://ko.javascript.info
Node.js 디자인패턴