我花了很多时间试图抓住我的应用中的错误。最后我把这段代码分开了,这对我来说似乎很奇怪。
var Model = Backbone.Model.extend({
myProperty: []
});
var one = new Model();
var two = new Model();
one.myProperty.push(1);
console.log(two.myProperty); //1!!
背后的原因是什么?为什么会这样呢?如何在代码中避免这种类型的错误?
答案 0 :(得分:3)
JavaScript中的继承是典型的 - 对象可以直接引用prototype chain中更高的属性。
在您的示例中,one
和two
都共享一个公共原型,并且不为myProperty
提供自己的值,因此它们都直接引用Model.protoype.myProperty
。
您应该为实例化的每个模型创建新的myProperty
数组。 Model.initialize
是这种初始化的惯用场所 - 覆盖constructor
不必要地复杂。
var Model = Backbone.Model.extend({
initialize: function() {
this.myProperty = [];
}
});
或者,您可以将myProperty
作为模型的属性:
var Model = Backbone.Model.extend({
defaults: function() {
return {
myProperty: []
}
}
});
重要的是要注意defaults
是一个函数 - 如果你要使用一个简单的对象,你会遇到相同的共享引用问题。
答案 1 :(得分:1)
文档说:
构造函数/初始化新模型([attributes],[options])
创建模型实例时,可以传入属性的初始值,这些值将在模型上设置。如果定义初始化函数,则在创建模型时将调用它。
在极少数情况下,如果您希望获得幻想,可能需要覆盖构造函数,这允许您替换模型的实际构造函数。
因此,根据文档,您需要执行类似的操作来运行您的案例:
var Model = Backbone.Model.extend({
initialize: function() {
this.myProperty = [];
}
});
答案 2 :(得分:1)
实际上它是因为myProperty
是一个数组,如你所知,数组将通过引用存储。只是为了测试考虑以下代码:
var Model = Backbone.Model.extend({
myProperty: [],
messege: ''
});
var one = new Model();
var two = new Model();
one.messege = 'One!';
two.messege = 'Two!';
console.log(one.messege ); // 'One!'
console.log(two.messege ); // 'Two!'
围绕这个的替代方案可能是:
var Model = Backbone.Model.extend({
constructor: function() {
this.myProperty = [];
Backbone.Model.apply(this);
}
});
var one = new Model();
one.myProperty.push(1);
var two = new Model();
console.log(two.myProperty); // []