一个实例中的Backbone Model更改数据会影响另一个实例

时间:2013-10-06 21:03:45

标签: backbone.js pass-by-reference javascript backbone-model

使用Backbone.Model

时,我遇到了一个奇怪的错误

所以我的模型声明如下:

var MyMode = Backbone.Model.extend({
   defaults:{
      'someList': []
   },

   initialize: function(){
      _.bindAll(this, 'toString', 'castFromString');
   },

   toString: function(){
      return this.get('hierarchyNameList').join('+');
   },

   castFromString: function(str){
      var strArray = [], index = 0;
      if (str) {
         strArray = str.split('+');
      }
      for (index = 0; index < strArray.length; index++){
         this.get('hierarchyNameList').push(strArray[index]);
      }
   }
});

然后我试着测试它

(function () {
'use strict';

var assert = function(condition, message) {
    if (condition !== true) {
        throw message || "Assertion failed";
    }
};

var mA = new MyModel({'someList': ['a','b','c']});
var mB = new MyModel();
mB.castFromString('a+b+c');

//I have a added a equals function to array prototype and tested it
assert(mA.get('someList').equals(mB.get('someList')));     //true

var mC = new MyModel(mA.toJSON());    //behaves as expected
var mD = new MyModel();   //for some reason its list already contains the list from B
mD.castFromString(mB.toString());    //since castFromString used push, now B and D both has array of length 6

assert(mC.equals(mA));    //success
assert(mC.equals(mD));    //fail, mc has arrayLength 3, mD has 6


 }).call(this);

实际代码比这更复杂,但我认为这是我可能做错了什么,有关为什么会发生这种情况的任何建议?提前谢谢!

1 个答案:

答案 0 :(得分:3)

问题在于你的默认值

defaults:{
  'someList': []
},
JavaScript中的

对象通过引用而不是值传递。这意味着您未明确指定someList值的所有实例将共享在上面的defaults定义中创建的数组。为避免这种情况,您可以将defaults定义为函数:

defaults: function () {
    return { 'someList': [] };
},

这将为MyModel的每个实例创建新数组,因此它们不会共享相同的数组。