TL;DR
var BaseClass = function (bar) {
this.foo = bar;
};
BaseClass.prototype.doSomething = function () {
console.log("from base class");
};
var DerivedClass = function () {
BaseClass.apply(this, arguments);
};
DerivedClass.prototype = Object.create(BaseClass.prototype);
DerivedClass.prototype.doSomething = function () {
BaseClass.prototype.doSomething.call(this);
console.log("from derived class");
};
var cls1 = new DerivedClass('I am cls1');
cls1.doSomething();
// -> from base class
// -> from derived class
console.log(cls1.foo);
// -> "I am cls1"
更新
感谢@HMR 的评论,我正在更新我的答案(请参阅下面的评论,非常有用):
- “在设置
DerivedClass 的原型时,您不应该创建BaseClass 的新实例,请使用Object.create(如果需要,还可以填充它)”
- “您还忘记初始化
BaseClass 并通过拥有 BaseClass.apply(this,arguments) 来获取它的实例变量的所有权”
1/ 使用Object.create
var BaseClass = function () {
this.foo = 'bar';
};
BaseClass.prototype.doSomething = function () {
console.log("base class");
};
var DerivedClass = function () {
};
DerivedClass.prototype = Object.create(BaseClass.prototype);
注意事项:
-
Object.create 将Base 的原型“复制”到Derived
-
this.foo 的公共属性没有复制到 Derived(因为它不是原型的一部分)- 见下文第 2 点/
更多关于Object.createhere的信息。
2/BaseClass.apply(this, arguments)
如上所述,this.foo 不适用于Derived 实例。为了使其可用,我们需要将 Base 构造函数应用到 Derived 构造函数中。
所以Base (this.foo,..) 的所有privileged 属性都应用于Derived 的新实例。
var DerivedClass = function () {
// Calls `Base` constructor with `Derived` context
BaseClass.apply(this, arguments);
};
DerivedClass.prototype = Object.create(BaseClass.prototype);
关于流行的HMR's answer中的javascript继承的更多细节。
为了比较和教育目的,我留下了我原来的答案。
您的技术的问题(虽然它可以按预期工作)是doSomething 方法被复制到BaseClass 的每个实例(因为它被声明为简单的public 属性)。
为避免这种情况,从而共享doSomething 方法在BaseClass 的所有实例中,您应该将其添加到prototype 的BaseClass:
var BaseClass = function () {
};
BaseClass.prototype.doSomething = function () {
console.log("base class");
};
您不会注意到最终结果有任何差异,但这样一来,doSomething 方法是“继承”,而不是复制。
现在知道了,用Javascript实现prototypal inheritance:
// Derived Class 1
var DerivedClass1 = function () {
};
DerivedClass1.prototype = new BaseClass();
var cls1 = new DerivedClass1();
cls1.doSomething();
// -> "base class"
// Derived Class 2
var DerivedClass2 = function () {
};
DerivedClass2.prototype = new BaseClass();
DerivedClass2.prototype.doSomething = function () {
console.log("derived class (2)");
};
var cls2 = new DerivedClass1();
cls2.doSomething();
// -> "derived class (2)"
奖励,如果你想从 DerivedClass 调用 parent 方法:
// Derived Class 3
var DerivedClass3 = function () {
};
DerivedClass3.prototype = new BaseClass();
DerivedClass3.prototype.doSomething = function () {
BaseClass.prototype.doSomething.call(this);
console.log("derived class (3)");
};
var cls3 = new DerivedClass1();
cls3.doSomething();
// -> "base class"
// -> "derived class (3)"