: 자바스크립트는 프로토타입 기반 언어이다. 모든 객체들이 클래스로 정의해놓은 메소드와 속성을 상속받기 위한 템플릿으로써 프로토타입 객체를 가진다.
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 디자인패턴
