我正在开发一个使用原型(prototype)继承的 JavaScript 项目。我决定使用它的方式如下:
var MySuperClass = function (param) {
this.prop = param;
};
MySuperClass.prototype.myFunc = function () {
console.log(this.prop);
};
var MySubClass = function (param) {
MySuperClass.call(this, param);
};
MySubClass.prototype = new MySuperClass();
MySubClass.prototype.constructor = MySubClass;
var obj = new MySubClass('value');
obj.myFunc();
随着对继承的强调。
问题在于,如果我在每个类(父类(super class)和子类)的构造函数中放置一个 console.log,父类(super class)将被调用两次,一次是在它通过 MySubClass 传递到子类时.prototype = new MySuperClass();
没有任何参数,当它在子类的构造函数中被“构造函数被盗”时,有一次带参数。
如果我随后尝试保存这些参数(意味着我必须添加逻辑来处理空参数),这可能会导致错误。
现在如果我这样做:
var MySubClass = function (param) {
MySuperClass.call(this, param);
};
MySubClass.prototype = MySuperClass;
MySubClass.prototype.constructor = MySubClass;
一切似乎都正常工作,但我以前从未见过有人这样做(在我的谷歌搜索中)。
任何人都可以向我解释第二个是否不正确以及如何不正确(它似乎类似于 Crockford 继承函数)以及如何修复第一个不触发两次,如果可以的话?
最佳答案
这样做不是正确的解决方案:
MySubClass.prototype = MySuperClass;
您将函数本身设置为原型(prototype)而不是原型(prototype)对象,因此您没有继承您期望的内容。
但你是对的。这样做会调用构造函数,这可能会导致问题。
MySubClass.prototype = new MySuperClass();
解决方案是使用Object.create
来设置继承。它为您提供了一个继承自所提供对象的新对象,但不调用任何构造函数。
MySubClass.prototype = Object.create(MySuperClass.prototype);
现在您有一个分配给 MySubClass.prototype
的对象,该对象继承自 MySuperClass.prototype
,但您不必实际调用构造函数。
非 ES5 兼容的实现不支持 Object.create
,但您可以为它制作一个(部分) shim。
if (!Object.create) {
Object.create = function(proto) {
function F(){}
F.prototype = proto;
return new F();
};
}
同样,这不是一个完整的 shim,但它模拟的足以创建继承对象,而无需调用引用原型(prototype)对象的构造函数。
关于javascript - 原型(prototype)继承调用构造函数两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13198782/