【问题标题】:Why are children models added to both parent models?为什么将子模型添加到两个父模型中?
【发布时间】:2015-03-09 02:03:54
【问题描述】:

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

JS斌: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,孩子也会被推送到两个父模型?

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    因为它们共享一个 children 数组:设置默认值时,它们是通过赋值来设置的,并且被赋值的是对数组的引用,而不是数组的 副本 .例如,出于同样的原因,下面的 ab 引用同一个数组:

    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功能,所以他们可能有原因)。

    【讨论】:

    • 感谢您的清晰解释。我什至没有考虑过这个问题与以这种方式设置默认值有关。
    猜你喜欢
    • 2012-04-11
    • 2018-08-24
    • 2012-10-28
    • 1970-01-01
    • 2019-10-30
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多