Lorenzo Polidori의 답변에 설명 된 표준 프로토 타입 상속 방법을 기반으로하는 내 솔루션은 다음과 같습니다 .
먼저 다음과 같은 도우미 메서드를 정의하여 시작합니다.이를 통해 나중에 이해하기 쉽고 더 읽기 쉽습니다.
Function.prototype.setSuperclass = function(target) {
this._superclass = target;
this.prototype = Object.create(this._superclass.prototype);
this.prototype.constructor = this;
};
Function.prototype.getSuperclass = function(target) {
return this._superclass;
};
Function.prototype.callSuper = function(target, methodName, args) {
if (arguments.length < 3) {
return this.callSuperConstructor(arguments[0], arguments[1]);
}
if (args === undefined || args === null) args = [];
var superclass = this.getSuperclass();
if (superclass === undefined) throw new TypeError("A superclass for " + this + " could not be found.");
var method = superclass.prototype[methodName];
if (typeof method != "function") throw new TypeError("TypeError: Object " + superclass.prototype + " has no method '" + methodName + "'");
return method.apply(target, args);
};
Function.prototype.callSuperConstructor = function(target, args) {
if (args === undefined || args === null) args = [];
var superclass = this.getSuperclass();
if (superclass === undefined) throw new TypeError("A superclass for " + this + " could not be found.");
return superclass.apply(target, args);
};
이제를 사용하여 클래스의 수퍼 클래스를 설정할 SubClass.setSuperclass(ParentClass)수있을뿐만 아니라 다음을 사용하여 재정의 된 메서드를 호출 할 수도 있습니다 SubClass.callSuper(this, 'functionName', [argument1, argument2...]).
function Transform() {
this.type = "2d";
}
Transform.prototype.toString = function() {
return "Transform";
}
function Translation(x, y) {
Translation.callSuper(this, arguments);
this.x = x;
this.y = y;
}
Translation.setSuperclass(Transform);
Translation.prototype.toString = function() {
return Translation.callSuper(this, 'toString', arguments) + this.type + " Translation " + this.x + ":" + this.y;
}
function Rotation(angle) {
Rotation.callSuper(this, arguments);
this.angle = angle;
}
Rotation.setSuperclass(Transform);
Rotation.prototype.toString = function() {
return Rotation.callSuper(this, 'toString', arguments) + this.type + " Rotation " + this.angle;
}
translation = new Translation(10, 15);
console.log(translation instanceof Transform);
console.log(translation instanceof Translation);
console.log(translation instanceof Rotation);
console.log(translation.toString())
물론 헬퍼 함수를 사용하더라도 여기의 구문은 꽤 어색합니다. 고맙게도 ECMAScript 6에서는 훨씬 더 예쁘게 만들기 위해 몇 가지 구문 설탕 ( 최대 최소 클래스 )이 추가되었습니다. 예 :
class Transform {
constructor() {
this.type = "2d";
}
toString() {
return "Transform";
}
}
class Translation extends Transform {
constructor(x, y) {
super();
this.x = x;
this.y = y;
}
toString() {
return super(...arguments) + this.type + " Translation " + this.x + ":" + this.y;
}
}
class Rotation extends Transform {
constructor(angle) {
super(...arguments);
this.angle = angle;
}
toString() {
return super(...arguments) + this.type + " Rotation " + this.angle;
}
}
translation = new Translation(10, 15);
console.log(translation instanceof Transform);
console.log(translation instanceof Translation);
console.log(translation instanceof Rotation);
console.log(translation.toString())
ECMAScript 6은이 시점에서 아직 초안 단계에 있으며 내가 아는 한 주요 웹 브라우저에서는 구현되지 않습니다. 그러나 원한다면 Traceur 컴파일러 와 같은 것을 사용 ECMAScript 6하여 평범한 오래된 ECMAScript 5기반 JavaScript 로 컴파일 할 수 있습니다 . 여기에서 Traceur를 사용하여 컴파일 된 위의 예제를 볼 수 있습니다 .