2012-03-09 63 views
1

对JavaScript/BackboneJS的工作原理感到困惑。让我们看看下面的例子: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的“类”全新副本,所以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! 

混乱的部分是整型变量“指标”,其实0作为预期,但阵“清单”已经包含了从以前的初始化值。这是怎么回事?

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

+2

我不知道骨干,但似乎'list' /'index'是放在原型中,所以它们在两种情况下都指向相同的价值。在每个实例的基础上对它们进行初始化设置:http://jsfiddle.net/fqZTp/4/。不过,我不确定这是否是答案。 – pimvdb 2012-03-09 12:43:19

+1

这确实是答案。请参阅http://documentcloud.github.com/backbone/docs/backbone.html#section-149以获取其扩展函数的实现细节。 – TheShellfishMeme 2012-03-09 13:02:42

回答

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); 
    } 
}); 
+0

这很好。但是,为什么(int)“index”变量像对象变量一样行为?它不会坚持价值。而(数组)“列表”变量行为像一个静态?我认为他们都坚持价值,最后的回报应该是:this.index = 1;这个。列表= [1]; – 2012-03-09 13:44:47

+1

@ViliusPau - 看看[这个答案](http://stackoverflow.com/a/1534286/29995) - 这是一个*优秀*的解释。 – 2012-03-09 14:16:24