推动Backbone的属性

时间:2014-12-19 13:55:56

标签: javascript backbone.js

我花了很多时间试图抓住我的应用中的错误。最后我把这段代码分开了,这对我来说似乎很奇怪。

var Model = Backbone.Model.extend({
    myProperty: []
});

var one = new Model();
var two = new Model();
one.myProperty.push(1);
console.log(two.myProperty); //1!!

背后的原因是什么?为什么会这样呢?如何在代码中避免这种类型的错误?

3 个答案:

答案 0 :(得分:3)

JavaScript中的继承是典型的 - 对象可以直接引用prototype chain中更高的属性。

在您的示例中,onetwo都共享一个公共原型,并且不为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 = [];
    }
});

来源:http://backbonejs.org/#Model-extend

答案 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); // []