[JS] 프로토타입 객체
생성자 안에서 메서드를 정의하는 방식의 문제점
function Circle(center, radius) {
this.center = center;
this.radius = radius;
this.area = function () {
return Math.PI * this.radius ** 2;
};
}
const c1 = new Circle({ x: 0, y: 0 }, 2.0);
const c2 = new Circle({ x: 0, y: 1 }, 4.0);
const c3 = new Circle({ x: 1, y: 0 }, 5.0);
Circle 안에 면적을 구하는 area 메서드를 정의하였다. Circle 생성자로 생성한 인스턴스 c1,c2,c3는 같은 메서드를 포함하게 된다.
이는 같은 작업을 하는 메서드를 인스턴스 갯수만큼 생성하는 것이므로,
그만큼 메모리 낭비가 일어나게 된다.
프로토타입 객체
이러한 문제는 프로토타입 객체에 메서드를 정의하여 해결할 수 있다.
function Circle(center, radius) {
this.center = center;
this.radius = radius;
}
Circle.prototype.area = function () {
return Math.PI * this.radius ** 2;
};
const c1 = new Circle({ x: 0, y: 0 }, 2.0);
const c2 = new Circle({ x: 0, y: 1 }, 4.0);
const c3 = new Circle({ x: 1, y: 0 }, 5.0);
console.log(c1.area()); // 12.566370614359172
__proto__
프로퍼티는 그 객체에게 상속을 해 준 부모 객체를 가리킨다.
따라서 객체는 __proto__
프로퍼티가 가리키는 부모 객체의 프로퍼티를 사용할 수 있다.
인스턴스 c1, c2, c3는 생성자로 Circle을 사용하였고, __proto__
는 생성자인 Circle의 prototype object를 가리키고 있다. 따라서, 인스턴스들은 Circle 프로토타입 객체가 갖고 있는 area 메서드를 사용할 수 있게 된다.
이렇게 함으로써 인스턴스에 메서드를 추가하지 않고도, 인스턴스들은 메서드를 사용할 수 있다. 결과적으로 메모리 낭비를 막을 수 있다.
프로토타입 객체의 프로퍼티
함수가 정의될 때 함수 객체
와 Prototype Object
이 생긴다.
- 함수 객체는
prototype
프로퍼티를 갖고 있다.- prototype property는 Prototype Object를 가리킨다.
- 생성된 Prototype object는 함수 객체의
prototype
프로퍼티를 통해 접근할 수 있다. - 이 때, prototype object는 함수 객체만 갖고 있다. 단일 객체가 만들어질 때는 생기지 않는다.
- Prototype Object는
constructor
와__proto__
를 갖고 있다.- constructor는 생성된 함수 객체의 참조를 갖고 있다.
__proto__
는Prototype Link
로서 생성자의 Prototype Object를 가리킨다.- 프로토타입 객체의
__proto__
는 기본적으로 Object.prototype을 가리킨다. 즉, 프로토타입 객체의 프로토타입은 Object.prototype이다.
프로토타입 객체 교체
- 함수 객체의 프로토타입 프로퍼티를 교체할 때는 교체할 객체에 constructor 프로퍼티로 생성자의 참조를 대입해야 한다.
function Circle(center, radius) {
this.center = center;
this.radius = radius;
}
Circle.prototype = {
constructor: Circle,
area() {
return Math.PI * this.radius ** 2;
},
};
const c1 = new Circle({ x: 0, y: 0 }, 2.0);
console.log(c1.area()); // 12.566370614359172
인스턴스가 프로토타입을 상속받는 시기
- 인스턴스의 프로토타입은 생성자가 인스턴스를 생성할 때 갖고 있던 프로토타입 객체이다.
- 인스턴스 생성 후, 생성자의 prototype 프로퍼티를 다른 객체로 교체하여도 인스턴스의 프로토타입은 바뀌지 않는다.
function Circle(center, radius) {
this.center = center;
this.radius = radius;
}
const c1 = new Circle({ x: 0, y: 0 }, 2.0);
Circle.prototype = {
constructor: Circle,
area() {
return Math.PI * this.radius ** 2;
},
};
console.log(c1.area()); // TypeError: c1.area is not a function
c1 인스턴스의 프로퍼티는 Circle이 생성되는 시점의 프로퍼티를 상속받게 된다. c1인스턴스 생성 후, Circle의 프로토타입 프로퍼티를 교체하여도 교체한 객체로부터는 프로퍼티를 상속받지 않는다.
- 인스턴스 생성 후 프로토타입 객체에 프로퍼티를 추가한다면, 인스턴스는 추가된 프로퍼티를 사용할 수 있다.
function Circle(center, radius) {
this.center = center;
this.radius = radius;
}
const c1 = new Circle({ x: 0, y: 0 }, 2.0);
Circle.prototype.area = function () {
return Math.PI * this.radius ** 2;
};
console.log(c1.area()); // 12.566370614359172
출처
- 모던 자바스크립트 입문
- 프로토타입 이해하기
- 자바스크립트 기초 - Object prototype 이해하기
Author And Source
이 문제에 관하여([JS] 프로토타입 객체), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yejineee/프로토타입-객체저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)