好的,我已经修改了大部分技术来实现JavaScript OOP中的继承。
作为一名Java程序员,我对经典方法很感兴趣,但这就是问题所在;说我想创建Animal
类(我知道它不是真正的类,但让我使用这个术语),如下所示:
function Animal(name){
this.name = name;
}
Animal.prototype.getName = function() {
return this.name;
}
重要的是要注意,这是我的第一个意图中的具体类,我想实例化它,而不是仅仅将它用作超类。我可以创建几个Animal
个实例,每个实例都有自己的名称。
扩展此类的一种可能方法是执行以下操作:
function Cat(name, owner) {
this.name = name;
this.owner = owner;
}
// ALTERNATIVE 1:
Cat.prototype = Object.create(Animal.prototype);
// ALTERNATIVE 2:
Cat.prototype = new Animal('LOLA');
// END OF ALTERNATIVES
Cat.constructor.prototype = Cat;
Cat.prototype.jump = function() {
alert(this.name + " jumping");
}
使用 ALTERNATIVE 1 我们只是继承了超类的方法,实际上我们需要重新定义Cat中的name
属性。由于 ALTERNATIVE 2 实际上没有任何变化,我们在链中还有一个对象,它拥有一个非常无用的name
属性:对于所有Cat
个实例都是一样的。
这里的要点是我已经用自己的名字编写了Animal
类,我只要将它扩展就把它扔掉。我想要的是继承属性和方法的方法,最重要的是,我希望能够重用Animal
构造函数。
答案 0 :(得分:0)
继承基础构造函数属性的传统方法如下:
function Cat(name, owner) {
Animal.call(this, name); // call the base constructor
this.owner = owner;
}
Cat.prototype = new Animal;
Cat.prototype.constructor = Cat;
Cat.prototype.jump = function () {
alert(this.name + " jumping");
};
以上代码与其他语言的以下类相同:
class Cat extends Animal {
constructor(name, owner) {
super(name);
this.owner = owner;
}
jump() {
alert(this.name + " jumping");
}
}
继承属性的新方法完全相同,除了我们用new Animal
替换Object.create(Animal.prototype)
。我们更喜欢新方式的原因是:
new Animal
是不必要的开销。无论如何,Cat
构造函数再次调用它。new Animal
可能不会返回空白对象。它可能会为对象添加一些属性。new Animal
调用什么参数。因此,称之为没有任何意义。因此,首选的继承方式是:
function Cat(name, owner) {
Animal.call(this, name); // call the base constructor
this.owner = owner;
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
Cat.prototype.jump = function () {
alert(this.name + " jumping");
};
请注意,调用基础构造函数很重要,因为它可能会进行一些初始化,这是实例正常工作所必需的。
如果您有兴趣以经典风格编写JavaScript代码,那么请查看描述原型类同构的following answer。以下代码取自以上答案:
function CLASS(prototype, base) {
switch (typeof base) {
case "function": base = base.prototype;
case "object": prototype = Object.create(base, descriptorOf(prototype));
}
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
function descriptorOf(object) {
return Object.keys(object).reduce(function (descriptor, key) {
descriptor[key] = Object.getOwnPropertyDescriptor(object, key);
return descriptor;
}, {});
}
使用CLASS
函数,我们可以在JavaScript中定义伪类,如下所示:
var Animal = CLASS({
constructor: function (name) {
this.name = name;
},
getName: function () {
return this.name;
}
});
var Cat = CLASS({
constructor: function (name, owner) {
Animal.call(this, name);
this.owner = owner;
},
jump: function () {
alert(this.name + " jumping");
}
}, Animal);
还有其他方法可以在JavaScript中进行继承。我建议您阅读Why Prototypal Inheritance Matters上的博文,了解有关JavaScript继承的更多信息。