继承_.extend的Javascript设计方法

Javascript design approach for inheritance with _.extend

本文关键字:方法 Javascript extend 继承      更新时间:2023-09-26

我正在使用一个JavaScript应用程序,它使用Underscore.js来处理大量继承。对象定义的标准模式是在变量中定义基本对象,然后直接定义其原型,如下所示:

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);

呃! !检查下划线文档,了解它的作用:它创建了一个new Parent实例,并将name属性(可能还有一些继承的属性)复制到它。然后,它会把那个物体扔掉。为什么?我不知道。

有一种模式叫做寄生继承,它的工作原理有点像mixins,至少 return修改后的对象变成了"子实例"。但就目前而言,这完全没有用。

什么是可以接受的?

_.extend(this, new Parent());

将复制实际子实例上的属性。但还有一个更简单的解决方案——直接在新实例上创建它们:

Parent.call(this);

我试了一个_.extend( Child.prototype, { …,但似乎没有帮助。

嗯,这是朝着正确方向迈出的一步。在上面的"super"调用旁边,你还想在子原型上拥有父类的共享(prototype)属性。你可以做

_.extend(Child.prototype, Parent.prototype, {
    loadData: …
});

将它们(然后是新的,特定于子对象的属性)复制到原型对象上,但是标准的解决方案是创建一个(动态的,原型的)继承自Parent.prototype的对象:

Child.prototype = _.extend(Object.create(Parent.prototype), {
    loadData: …
});