2012-04-23 58 views
11

在过去的两天里,我一直在抨击这个问题。出于某种原因,骨干网正在跨继承的子模型共享父实例数据。这里有一个例子:Backbone.js:模型继承导致共享数据

var Base = Backbone.Model.extend({ 

    index : [] 

}); 

var Group = Base.extend({ 

    initialize : function() { 
    this.index.push('from group'); 
    } 

}); 


var User = Base.extend({ 

    initialize : function() { 
    this.index.push('from user'); 
    } 

}); 


var user = new User(); 
console.log(user.index); // ['from user'] 


var group = new Group(); 
console.log(group.index) // ['from user', 'from group'] 

我正在寻找的是:

console.log(user.index); // ['from user'] 
console.log(group.index) // ['from group'] 

任何见解?

谢谢! Matt

回答

14

您所遇到的实际上是JS通过引用而不是按值传递对象(或数组)的方式的副产品。如果你希望用户和组的索引不同,只需在初始化函数中将它初始化为一个数组。

var Base = Backbone.Model.extend({ 

initialize: function() { 
    this.index = []; 
} 


}); 
+0

感谢您的回答。我真的希望'extend()'克隆对象/数组可以避免这个问题。看起来应该避免在父类中定义数组和对象的做法,因为这可能会导致意想不到的后果。 – Matt 2012-04-23 01:00:39

+3

有理由在这样的类中定义对象或数组,但是你的意图是使用index作为实例变量,这样它对于每个实例都是唯一的,并且在类变量等所有实例之间共享。如果你想要实例变量,那么是的,你不应该在传递给扩展的对象中定义它们,但是如果你想要类变量,那么是的,它很好。如Skylar所示,在父项的构造函数中定义实例变量非常好。 – chubbsondubs 2012-04-23 01:12:47

6

索引构件类似于类变量,它是在碱的原型链,因此由所有实例共享只是因为它包含也被共享的方法。尝试切换实例化用户和组的顺序。现在索引包含什么?这是相反的吗?那是因为他们分享了传递给对象的所有东西。

为了使它成为一个实例变量,您需要在Base的构造函数中实例化它,并让每个子类从它们各自的构造函数中调用该构造函数。像:

var Base = Backbone.Model.extend({ 
    initialize: function() { 
     this.index = []; 
    } 
}); 

var User = Base.extend({ 
    initialize: function() { 
     Base.prototype.initialize.call(this); 
     this.index.push('User'); 
    } 
}); 

// repeat it for group. 
+0

感谢您的回答。这是解决问题的另一种方法。 – Matt 2012-04-23 01:01:17