BackboneJS中意外的构造函数/扩展行为

时间:2012-03-09 12:37:38

标签: javascript constructor backbone.js extend

对JavaScript / BackboneJS的工作方式感到困惑。让我们考虑以下示例:

window.MyView = Backbone.View.extend({
    index: 0,
    list: [],        
    initialize: function () {
        console.log("Initializing MyView");
        console.log("this.index = " + this.index);
        console.log("this.list = [" + this.list.join(',') + "]");
        this.index++;
        this.list.push(this.index);
    }
});

var first = new MyView(),
    second = new MyView();

我在这里期待的是新的MyView()将创建一个干净的window.MyView“class”副本,所以outbut将是:

Initializing MyView
this.index = 0
this.list = []

Initializing MyView
this.index = 0
this.list = []

但相反,我有

Initializing MyView
this.index = 0
this.list = []

Initializing MyView
this.index = 0
this.list = [1] // Very unexpected!

令人困惑的部分是整数变量“index”实际上是0,正如预期的那样,但是数组“list”已经包含了之前初始化的值。怎么会这样?

演示http://jsfiddle.net/fqZTp/3/

1 个答案:

答案 0 :(得分:3)

这两个答案很好地解释了listindex之间的不同行为:

总结一下:

  • listindex都存在于MyView的原型上。
  • 创建new MyView()后,initialize()在新创建的实例的上下文中运行(即不是原型)。
  • 当您将push()某些内容发送到list时,您会将其推送到原型的引用列表对象上。你根本没有更新对列表的引用,只是阅读它。
  • 当您index++时,这实际上会在幕后执行分配this.index = this.index + 1)。当您为对象分配内容时,原型上是否存在它并不重要 - 您将其分配给该特定实例。原型不会改变。

对于您期望的行为,只需在initialize函数中设置两个属性:

window.MyView = Backbone.View.extend({
    initialize: function () {
        this.index = 0;
        this.list = [];

        this.index++;
        this.list.push(this.index);
    }
});