为什么将儿童模型添加到两个父模型中?

Jos*_*osh 1 javascript backbone.js

我在下面有一个示例,它创建了两个父模型,然后使用自定义函数将子模型推送到父模型中.

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);
Run Code Online (Sandbox Code Playgroud)

预期产出:

"父母1名儿童总数:0"

"父母2名儿童总数:2"

实际产量:

"父母1名儿童总数:2"

"父母2名儿童总数:2"

题:

为什么孩子被推到两个父模型,即使我只有指定的孩子被推到父2?

T.J*_*der 5

因为它们共享一个children数组:当设置默认值时,它们由赋值设置,并且分配的是对数组的引用,而不是数组的副本.例如,对于相同的原因,a并且b下面是指相同的数组:

var a = [];
var b = a;
Run Code Online (Sandbox Code Playgroud)

......而不是直接通过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;
  }
});
Run Code Online (Sandbox Code Playgroud)

这就是文档所说的内容:

请记住,在JavaScript中,对象是通过引用传递的,因此如果将对象包含为默认值,则它将在所有实例之间共享.相反,定义defaults为一个函数.

也许可以使用constructor替代方法来做到这一点,但我不会展示一个例子,因为我不使用Backbone并且可以轻易地显示一些误导性的东西(并且文档指向使用defaults函数,因此它们可能有原因) .