프로토타입 체이닝을 공부하면서 상속에는 두 가지 종류가 있다는 것을 새로 알았다. MDN ecmascript 2015 class 페이지를 참고하여 별도의 예제를 작성하는 방식으로 두 상속의 특징과 차이점을 정리했다.
__proto__
내부에 다시 __proto__
프로퍼티가 이어진 것을 프로토타입 체인이라고 하고, 이 체인을 따라 검색하는 것을 프로토타입 체이닝이라고 한다. Object.prototype
이 프로토타입 체이닝의 최상단에 위치한다.프로토타입 상속을 위해서는 아래와 같은 과정이 필요하다.
1. .call
메서드를 이용하여 this 바인딩
2. Object.create
를 통해 하위 객체의 프로토타입이 상위 객체의 프로토타입을 가리키도록 하기
3. 하위 객체 프로토타입의 constructor가 하위 객체 자신을 가리키도록 수정하기
// name, price 두 가지 정보를 받는 생성자 함수
function Product (name, price) {
this.name = name;
this.price = price;
}
function Food (name, price) {
// Product를 호출하며 this를 new Food()를 통해 생성되는 인스턴스로 지정 =>
// Product 함수 내부 코드가 실행되며 new Food()로 만들어지는 인스턴스에 name, price 속성값이 생성된다.
Product.call(this, name, price); // 1번
this.category = 'food';
}
Food.prototype = Object.create(Product.prototype); // 2번
Food.prototype.constructor = Food; // 3번
ECMAScript 2015에서 공개된 클래스 문법에 따라 클래스도 상속할 수 있다.
위에서 설명한 프로토타입 상속과는 조금 다른 방식이다.
위의 예제를 Class 스타일로 변경했다.
// 상위 클래스
class Product {
constructor (name, price) {
this.name = name;
this.price = price;
}
noticePrice () {
console.log(`It costs $${price}!`);
}
}
하위 클래스를 생성하기 위해서는 extends
와 super
라는 두 가지 키워드가 필요하다.
extends
는 클래스를 다른 클래스의 자식(하위 클래스)으로 만들기 위해 사용되는 키워드이다.super
는 상위 클래스의 constructor를 실행시키는 키워드이다. 상속 시 반드시 사용해야 하는 것은 아니지만, 이 키워드를 활용하면 상위 클래스의 속성을 모두 옮겨 적지 않아도 된다는 장점이 있다.// 하위 클래스 생성 (super 사용 x)
class Food extends Product { // extends 키워드
constructor (name, price, category) {
this.name = name;
this.price = price;
this.category = 'food'; // Product의 고유한 속성
}
}
// 하위 클래스 생성 (super 사용)
class Food extends Product {
constructor (name, price, category) {
super(name, price); // 상위 클래스의 멤버 상속
this.category = 'food'; // Product의 고유한 속성
}
}