我正试图掌握javascript继承。我的示例代码如下所示:
var example = example || {};
example.Classes = {};
(function() {
var example = example || {};
example.Classes = {};
var privateVar = 25;
function Superclass() {
this.x = privateVar;
}
Superclass.prototype = {
move: function(x){
this.x += x;
console.log("Superclass move",this.x);
},
dance: function(x){
this.x += x*2;
}
};
function Subclass() {
Superclass.apply(this, arguments);
this.y = 0;
};
Subclass.prototype = Object.create(Superclass.prototype);
Subclass.prototype.constructor = Subclass;
这是成功的延续:
Subclass.prototype.dance = function(x, y) {
this.x -= (x + privateVar);
this.y -= y;
console.log("Subclass dance", this.x, this.y)
};
example.Classes.Superclass = Superclass;
example.Classes.Subclass = Subclass;
window.example.Classes = example.Classes;
}());
var success = new example.Classes.Subclass();
success.dance(5,4);
success.move(6);
控制台输出:子类舞-5 -4 控制台输出:超类移动1
现在继续失败 - 这里有什么不对?为什么我不能用这种方式编写子类构造函数?
Subclass.prototype = {
dance: function(x, y) {
this.x -= (x + privateVar);
this.y -= y;
console.log("Subclass dance", this.x, this.y)
}
};
example.Classes.Superclass = Superclass;
example.Classes.Subclass = Subclass;
window.example.Classes = example.Classes;
}());
var failure = new example.Classes.Subclass();
failure.dance(5,4);
failure.move(6);
控制台输出:子类舞-5 -4 控制台输出:错误:failure.move不是函数
答案 0 :(得分:3)
为什么我不能用这种方式编写子类构造函数?
因为您正在吹走以前在Subclass.prototype
属性上的对象(来自Object.create(Superclass.prototype)
的属性)和将替换为对象的原型仅Object.prototype
只有一个属性dance
。
创建Subclass.prototype
对象后,您总是希望像以前一样扩充:
Subclass.prototype.dance = /*...*/;
不替换:
// Not this
Subclass.prototype = { dance: /*...*/ };
ES2015添加了一个方便的功能,用于将属性从一个对象(或一系列对象)合并到目标对象中:Object.assign
。它可以(大多数情况下)为旧的JavaScript引擎填充。使用它,你可以这样做:
Object.assign(Subclass.prototype, {
dance: function dance() { /* ... */ },
skip: function skip() { /* ... */ },
jump: function jump() { /* ... */ }
});
已经说过,在2016年,我建议使用ES2015中添加的class
功能(如果旧版JavaScript引擎有必要,请进行转换):
class Superclass {
constructor() {
//...
}
method() {
// ...
}
class Subclass extends Superclass {
constructor() {
super();
// ...
}
anotherMethod() {
// ...
}
}