2012-03-09 39 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