对象文字和原型继承?

时间:2014-10-10 00:05:19

标签: javascript underscore.js

在javascript中,我有一个对象字面值:

var objA = {
  doStuff: function() {
    // do objA stuff
  }
}

我扩展objA,并覆盖doStuff方法:

var objB = _.extend(objA, {
  doStuff: function() {
    // do objB stuff
  }
});

然而,现在当调用objB.doStuff()时,只有objB内容完成。

我想要完成objA和objB的工作。我尝试了以下方法:

var objB = _.extend(objA, {
  doStuff: function() {
    this.prototype.doStuff.call(this, arguments);
    // do objB stuff
  }
});
objB.__proto__ = objA;

然而,这不起作用。我想我不明白在扩展对象文字时原型继承是如何工作的。那么,这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

Unserscore的_.extend功能不会返回新对象。

它使用新属性返回扩展的同一对象。因此,您的objA具有新的doStuff功能。

相反,您可能希望使用_.clone,然后在doStuff上重写objB

答案 1 :(得分:1)

  

我希望objA和objB都能完成。

您必须明确地调用objA的方法:

var objB = _.extend({}, objA, {
  doStuff: function() {
    objA.doStuff.apply(this, arguments);
    // do objB stuff
  }
}, objA);

请注意,我正在添加一个空对象作为第一个参数,以便合并第一个objA的属性然后再合并。有关_.extend工作原理的详细信息,请参阅documentation

  

对象文字和原型继承?

目标文字当前不提供设置原型的方法。您可以使用Object.create创建具有特定原型的空对象,然后将其他属性合并到其中:

var objB = Object.create(objA);
// `merge` is a fictional function that copies properties from object to another
merge(objB, {
   doStuff: function() { ... }
});

您仍然可以通过明确引用它来调用objA的方法。


注意:在ES6最终确定并实施后,可能需要修改此部分。

ES6 中,您可能可以设置原型via the __proto__ property name

var objB = {
  __proto__: objA,
  doStuff: function() { }
};

或通过Object.setPrototypeOf

var objB = {...};
Object.setPrototypeOf(objB, objA);

然后,您应该可以通过objA关键字调用super方法:

var objB = {
  __proto__: objA,
  doStuff: function() {
    super.doStuff();
  }
};

答案 2 :(得分:0)

您在示例中所做的事实上不是继承,而只是创建和修改。要在Javascript中实现继承,它本身并不是您正在扩展的OBJECT。这是一个功能。对象不提供对其原型的直接访问,而函数也是如此。所以你所追求的可能更像是:

function ObjA() {
    return this;
}
ObjA.prototype.doStuff = function() {
    // do objA stuff
};

function ObjB() {
    return this;
}
ObjB.prototype = new ObjA();
ObjB.prototype.doStuff = function() {
    ObjA.prototype.doStuff.apply(this, arguments);
    // do objB stuff
}

var objA = new ObjA(),
    objB = new ObjB();