JS는 프로토타입 기반의 OOP 언어이다. JS는 객체 기반의 언어이며 JS를 이루는 거의 모든 것이 객체다.
1. 상속과 프로토타입
JS는 프로토타입 기반으로 상속을 구현하여 불필요한 중복을 제거한다. 예를 들어,
function Circle(radius) {
this.radius = radius;
this.getArea = function () {
return Math.PI * this.radius ** 2;
};
}
const circle1 = new Circle(1);
const circle2 = new Circle(2);
// Circle 생성자는 인스턴스를 생성할 때 마다 getArea 메서드를 중복 생성한다.
// getArea 메서드는 하나만 쓰는것이 바람직하다.
console.log(circle1.getArea === circle2.getArea); // false
// 프로토타입 사용!
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.getArea = function () {
return Math.PI * this.radius ** 2;
};
const circle1 = new Circle(1);
const circle2 = new Circle(2);
console.log(circle1.getArea === circle2.getArea); // false
프로토타입 기반의 상속을 통해 불필요한 중복을 제거한다.
2. 프로토타입 객체
모든 객체는 [[Prototype]]이라는 내부 슬롯을 가지며, 이 내부 슬롯 값은 프로토타입의 참조이다.
객체가 생성될 때 객체 생성 방식에 따라 프로토타입이 결정되고 [[Prototype]]에 저장된다.
모든 객체는 하나의 프로토타입을 가지며, 모든 프로토타입은 생성자 함수와 연결되어 있다.
__proto__는 접근자 프로퍼티다.
내부 슬롯은 프로퍼티가 아니므로, 원칙적으로 내부 슬롯과 내부 메서드에 직접 접근하거나 호출할 수 있는 방법을 제공하지 않는다. 하지만 일부 내부 슬롯과 내부 메서드에 한해 간접적으로 접근 가능하다.
프로토타입 체인은 단방향 링크드 리스트로 구현되어야 한다. 순환 참조하는 체인이 만들어지면 체인에서 프로퍼티를 검색할 때 무한 루프에 빠진다. 따라서 체크 없이 무조건 프로토타입을 교체할 수 없게 __proto__ 접근자 프로퍼티를 통해 프로토타입에 접근하고 교체하도록 구현되어 있다.
3. 프로토타입 체인
객체의 프로퍼티에 접근할 때 접근하려는 프로퍼티가 없다면 [[Prototype]] 내부 슬롯의 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색하며, 이를 프로토타입 체인이라고 한다.
이는 JS가 OOP의 상속을 구현하는 메커니즘이다.
프로토타입 체인의 최상위 객체는 언제나 Object.prototype이다. 따라서 모든 객체는 Object.prototype을 상속받는다. Object.prototype을 프로토타입 체인의 종점(end of prototype chain)이라 한다.
프로토타입 종점에서 프로퍼티를 검색할 수 없는 경우 undefined를 반환한다.
결국 프로토타입 체인은 상속과 프로퍼티 검색을 위한 메커니즘이라고 할 수 있다. 이에 반해 프로퍼티가 아닌 식별자는 스코프 체인에서 검색한다. 스코프 체인은 식별자 검색을 위한 메커니즘이다.
'모던자바스크립트-DeepDive' 카테고리의 다른 글
6. 브라우저의 렌더링 과정 (0) | 2024.10.03 |
---|---|
5. 배열 (2) | 2024.10.02 |
4. 클로저 (0) | 2024.10.02 |
3. 실행 컨텍스트 (0) | 2024.10.01 |
2. this (0) | 2024.10.01 |