* 프로토타입 객체
- 함수도 객체이므로 함수 객체는 기본적으로 prototype 프로퍼티를 갖고 있다.
- 프로토타입 객체의 프로퍼티는 읽기만 가능하고 수정은 불가능
- 프로토타입 체인
- 인스턴스가 프로토타입 객체의 메소드를 사용하면 메모리 낭비를 피할 수 있음.
// Circle 생성자
function Circle(center, radius){
this.center = center;
this.radius = radius;
}
// Circle 생성자의 prototype 프로퍼티에 area 메소드를 추가
Circle.prototype.area = function(){
return Math.PI * this.radius * this.radius;
}
var c1 = new Circle({x:0, y:0}, 2.0);
console.log(c1.area()); // 12.566370614359172
* 프로토타입 상속
1. 상속
- 프로토타입 상속을 하는 객체 지향 언어를 가리켜 프로토타입 기반 객체 지향 언어라 한다.
2. 프로토타입 체인
- 객체의 __proto__ 프로퍼티는 그 객체에게 상속을 해준 부모 객체를 가리킨다.
- 자신이 갖고 있지 않은 프로퍼티를 __proto__ 프로퍼티가 가리키는 객체를 차례대로 거슬러 올라가며 검색한다.
// 프로토타입 체인
var objA = {
name:"Tom",
sayHello: function(){
console.log("Hello! " + this.name);
}
};
var objB = {
name: "Huck"
};
objB.__proto__ = objA;
var objC = {};
objC.__proto__ = objB;
objC.sayHello(); // Hello! Huck
3. 일반적으로 상속하는 방법
- 생성자로 객체를 생성할 때 생성자의 prototype 프로퍼티에 추가하는 방법
- Object.create 메소드로 상속을 받을 프로토타입을 지정하여 객체를 생성하는 방법
4. 프롤토타입 가져오기
function F(){}
var obj = new F();
console.log(Object.getPrototypeOf(obj)); // F { }
* 프로토타입 객체의 프로퍼티
1. constructor 프로퍼티
- 함수 객체의 참조를 값으로 갖고 있다.
- 생성자와 생성자의 프로토타입 객체는 서로를 참조한다.
- 인스턴스가 어떤 생성자로 생성된 것인지 알아내는 방법으로 인스턴스가 가진 프로토타입의 constructor 프로퍼티 값을 확인함.
function F(){};
obj = new F();
console.log(obj.constructor); // [Function: F]
2. 내부 프로퍼티[[Prototype]]
- 함수 객체가 가진 프로토타입 객체의 내부 프로퍼티[[Prototype]]은 기본적으로 Object.prototype을 가리킨다.
unction F(){};
console.log(F.prototype.__proto__); // {}
3. 프로토타입 객체의 교체 및 constructor 프로퍼티
- 프로퍼티만 정의되어 있는 새로운 객체를 prototype 프로퍼티 값으로 대입하면 인스턴스와 생성자 사이의 연결 고리가 끊겨 버리기 때문에 주의해야 한다.
function Circle(center, radius){
this.center = center;
this.radius = radius;
}
Circle.prototype = {
constructor: Circle,
area : function() {
return Math.PI * this.radius * this.radius;
}
};
var c = new Circle({x:0, y:0}, 2.0);
console.log(c.constructor); // [Function: Circle]
console.log(c instanceof Circle); // true
4. 인스턴스 생성 후에 생성자의 프로토타입을 수정하거나 교체한 경우
- 인스턴스를 생성한 후에 생성자의 prototype 프로퍼티 값을 다른 객체로 교체해도 인스턴스의 프로토타입은 바뀌지 않음.
// 오류 발생
function Circle(center, radius){
this.center = center;
this.radius = radius;
}
var c = new Circle({x:0, y:0}, 2.0);
Circle.prototype = {
constructor: Circle,
area : function() {
return Math.PI * this.radius * this.radius;
}
};
console.log(c.area());
* 프로토타입의 확인
1. instanceof 연산자
- instanceof 연산자는 지정한 객체의 프로토타입 체인에 지정한 생성자의 프로토타입 객체가 포함되어 있는지를 판정한다.
- 인스턴스가 해당 생성자로 생성되었는지 여부가 아닌 인스턴스가 생성자의 프로토타입 객체를 상속 받았는지 확인한다.
function F(){};
var obj = new F();
console.log(obj instanceof F); // true
console.log(obj instanceof Object); // true
console.log(obj instanceof Date); // false
2. isPrototypeOf 메소드
- isPrototypeOf 메소드는 특정 객체가 다른 객체의 프로토타입 체인에 포함되어 있는지를 판정한다.
function F(){};
var obj = new F();
console.log(F.prototype.isPrototypeOf(obj)); // true
console.log(Object.prototype.isPrototypeOf(obj)); // true
console.log(Date.prototype.isPrototypeOf(obj)); // false