0

在尝试提出一个基本模型来处理我正在处理的应用程序域的所有类似实体时,我创建了:

  • 一个基本对象(实体):具有一些共享属性和初始化器,设置为原型
  • 一个产品对象(Product):从Entity“继承”。并包含“变体”列表
  • 变体对象(Variant):从实体“继承”。

Product.prototype = new Entity();

Variant.prototype = new Entity();

当我运行它时,发生了一些奇怪的事情:“产品”对象中的“变体”列表最终包含两个元素,这很好,但它们不是两个单独的“变体”实例,而是指向同一个内存空间。

我已经进行了一些调试(基于警报),以确保在填充 observableArray 的“for 循环”期间,一切正常。

var Product = function (data) {
var initial = data || {};
this.variants = ko.observableArray();
this.init(initial);
if (initial.variants != null) {
  for (var i = 0; i < initial.variants.length; i++) {

    // NOTE: this is the misterious line. Creating two instances
    //       of 'new Variant', ends up pushing a single instance. 
    this.variants.push(new Variant(initial.variants[i]));
    //-----------------------------------------------------------
    
    alert(this.variants()[i].name());
  }
}

我假设我缺少一些 Javascript 基础知识来弄清楚我做错了什么。

这是JsFiddle的完整示例。

4

1 回答 1

1

如果你将 observables 放在原型上,那么它们最终会在所有实例之间共享,而不是成为它们自己独立的 observables。observable 是一个在内部缓存其值的函数。因此,在这种情况下,每个实例都有相同函数的副本。

通常,您会希望避免将 observables 放在原型上,尽管您当然可以放置任何其他函数(通用处理程序、订阅回调和计算的 observable 读/写函数)。

如果您想创建一个从另一个具有可观察对象的结构继承,那么可以选择使用各种“混合”类型策略之一。

例如,您可以将基本构造函数应用于兄弟对象。

var Product = function(data) {
  Entity.call(this, data); //call the Entity constructor to add observables, etc.

  //do other Product stuff here
};

然后,您可以使Product原型等于Entity原型,或者更好地使原型在其链中Product具有原型,例如:Entity

Product.prototype = Object.create(Entity.prototype);

如果您支持较旧的浏览器,请寻找Object.create shim

更新示例:http: //jsfiddle.net/rniemeyer/7AnAz/

于 2013-01-25T20:28:22.083 回答