[javascript prototype] Prototype을 이용한 상속
아래 Circle
class는 duplicate
을 prototype property로 가지고 있습니다.Square
class에도 동일한 기능을 구현해야 한다면 반복적으로 duplicate
을 추가해야 될까요?
Shape
이라는 class를 만들고, duplicate
을 Circle
과 Square
에 모두 사용할 수 있게 할 수 있는 방법을 고민해 봅시다.
function Shape() {
}
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.duplicate = function() {
console.log("duplicate");
}
function Square() {
}
javascript에서 object를 통해 method를 요청하면, prototype chain에서 해당 method를 찾게 됩니다.
우리가 해줄 것은 Shape
이 Circle
과 Square
의 prorotype chain에 추가하는 것입니다.
우선 duplicate
을 Shape
의 prototype property로 정의합니다.
function Shape() {
}
Shape.prototype.duplicate = () => {
console.log("duplicate")
}
const circle = new Circle(1);
현재 Circle
의 prototype은 Object
입니다.Object.create
을 이용하면, 특정 prototype을 가진 object를 만들 수 있습니다.Circle
의 prototype을 Shape.prototype을 prototype으로 가진 object로 설정해 줍니다.
Circle.prototype = Object.create(Shape.prototype);
이렇게 prototype을 명시적으로 설정해주기 이전엔, 아래와 같이 Object.prototype
을 prototype으로 갖는 object가 Circle.prototype
으로 기본적으로 설정되어 있습니다.
Circle.prototype = Object.create(Object.prototype);
Circle의 prototype을 변경한 뒤 circle의 prototype을 확인해보면, Shape
으로 변경된 것을 확인할 수 있습니다.
circle.duplicate();
// "duplicate"
그럼 Square
에도 마찬가지로 Shape
을 prototype chain에 추가해주면 Shape
의 prototype property로 정의된 duplicate
을 사용할 수 있습니다.
Square.prototype = Object.create(Shape.prototype);
const sq = new Square();
sq.duplicate();
// "duplicate"
한가지 문제점은 prototype chain에 추가하면서 constructor가 변경된다는 점입니다.
Circle
의 constructor를 다시 설정하기 위해서 아래와 같이 constructor를 초기화 시켜줘야 합니다.
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
이것이 javascript에서 상속을 구현하는 방법입니다.
typescript에서 class A (ParentClass)
문법을 통해서 다른 OOP language의 상속구문과 비슷한 형태로 상속을 사용할 수 있게 해주지만, 결국 구현은 prototype chain을 이용한 상속입니다.