我在下面有一个示例,它创建了两个父模型,然后使用自定义函数将子模型推送到父模型中。
JS Bin:http://jsbin.com/hamuro/4/edit?html,console
var Child = Backbone.Model.extend({});
var Parent = Backbone.Model.extend({
defaults: {
children: []
},
addChild: function() {
var child = new Child();
this.get('children').push(child);
return child;
}
});
var parent1 = new Parent();
var parent2 = new Parent();
parent2.addChild();
parent2.addChild();
console.log('Parent 1 Total Children: ' + parent1.get('children').length);
console.log('Parent 2 Total Children: ' + parent2.get('children').length);
预期输出:
“父母1名儿童总数:0”
“父母2名儿童总数:2”
实际输出:
“父母1名儿童总数:2”
“父母2名儿童总数:2”
问题:
为什么孩子被推送到两个父模型,即使我只有指定的孩子被推送到parent2?
答案 0 :(得分:5)
因为它们共享一个children
数组:当设置默认值时,它们会通过赋值进行设置,而分配的内容是对数组的引用,而不是副本数组。例如,出于同样的原因,下面的a
和b
引用相同的数组:
var a = [];
var b = a;
...而不是直接通过defaults
机制。
相反,您指定了defaults
函数,每次都会调用它来创建一个不同的数组:
defaults
功能:
var Parent = Backbone.Model.extend({
defaults: function() [
return {
children: []
};
},
addChild: function() {
var child = new Child();
this.get('children').push(child);
return child;
}
});
这是the documentation在谈到的时候所说的:
请记住,在JavaScript中,对象是通过引用传递的,因此如果将对象包含为默认值,则它将在所有实例之间共享。相反,将
defaults
定义为函数。
也可以使用constructor
代替这一点,但我不会展示一个例子,因为我不使用Backbone并且可以轻松地显示一些误导性内容(并且文档指向使用defaults
函数,所以他们可能有原因。)