推送到主干中的属性

Pushing to properties in Backbone

本文关键字:属性      更新时间:2023-09-26

我花了很多时间试图在我的应用程序中捕获一个错误。 最终我把这段行为对我来说似乎很奇怪的代码分开。

var Model = Backbone.Model.extend({
    myProperty: []
});
var one = new Model();
var two = new Model();
one.myProperty.push(1);
console.log(two.myProperty); //1!!

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

JavaScript 中的继承是典型的 - 对象可以直接引用原型链中更高位置的属性。

在您的示例中,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是一个函数 - 如果要使用简单对象,则会遇到相同的共享引用问题。

实际上这是因为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); // []

文档说:

构造函数/初始化新模型([属性],[选项](

创建模型实例时,可以传入属性的初始值,这些值将在模型上设置。如果定义初始化函数,则会在创建模型时调用该函数。

在极少数情况下,如果你想变得花哨,你可能想要覆盖构造函数,这允许你替换模型的实际构造函数。

因此,按照文档,您需要执行以下操作来运行您的案例:

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

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