我正在使用一个 JavaScript 应用程序,该应用程序使用 Underscore.js 来处理大量继承。对象定义的标准模式是在变量中定义基本对象,然后直接定义其原型(prototype),如下所示:
var Parent = function()
{
this.name="parent";
this.loadData();
};
Parent.prototype = {
loadData: function()
{
this.say="parent loadData";
},
action: function()
{
return this.name+" says: '"+this.say+"'";
}
};
这工作正常并且相当容易阅读,但我对系统中处理继承的方式有点困惑。作者使用 _.extend
方法以相同的格式创建子对象,如下所示:
var Child = function()
{
this.name="child";
_.extend(this, new Parent());
};
Child.prototype= {
loadData: function()
{
this.say="child data loaded";
}
});
问题是,虽然核心属性似乎可以正常复制,但我似乎拥有父级而不是子级的方法。
var myParent = new Parent();
var myChild = new Child();
console.log( myParent.action() ); // "parent says: 'parent loadData'"
console.log( myChild.action() ); // "child says: 'parent loadData'"
我尝试了 _.extend( Child.prototype, { ...etc
但这似乎没有帮助。现在我可以回到我处理继承属性的方式过去的 Child.prototype.loadData=function()
但它会破坏应用程序其余部分使用的习惯用法,所以我想知道:这是 JavaScript 面向对象的标准方法吗?如果是的话它在任何地方都有名称/一些文档吗?有没有办法保持这个模型并让实际继承正常工作,同时保留可读的代码?
最佳答案
_.extend(new Parent(), this);
呃!检查underscore docs关于它的作用:它创建一个新的 Parent 实例并将 name
属性(可能还有一些继承的属性)复制到它。然后,它会将那个物体扔掉。为什么?我不知道。
有一种称为寄生继承的模式,其工作方式有点像mixins,它至少返回
s修改对象以成为“子实例”。但就目前而言,这完全没有用。
什么是可以接受的?
_.extend(this, new Parent());
将复制实际子实例上的属性。但还有一个更简单的解决方案 - 只需立即在新实例上创建它们即可:
Parent.call(this);
<小时/>
I tried a
_.extend( Child.prototype, { …
but that didn't seem to help.
嗯,这是朝着正确方向迈出的一步。除了上面的“ super ”调用之外,您还希望在子级原型(prototype)上拥有父级的共享(原型(prototype))属性。你可以做
_.extend(Child.prototype, Parent.prototype, {
loadData: …
});
将它们(然后是新的、子特定的属性)复制到原型(prototype)对象上,但是 standard solution是创建一个(动态地、原型(prototype)地)继承自 Parent.prototype
的对象:
Child.prototype = _.extend(Object.create(Parent.prototype), {
loadData: …
});
关于使用 _.extend 进行继承的 Javascript 设计方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24700074/