2013-05-21 138 views
0

我有我的對象這樣的功能:爲什麼這不被認爲是一種功能?

var time = { 

    warps : 3, 
    warpCounter : 50, 

    warp : function(){ 
     if (this.warps > 0){ 
      this.warps--; 
      this.warpLoop = 50; 
      this.warpLoop(); 
     } 
    }, 

    warpLoop : function(){ 
     setTimeout(function() { 
      this.increment();    
      if (warpCounter--){ 
      this.warpLoop(); 
      }else{ 
      if(this.warps > 0){ 
       htmlInteraction.enableButton('warp-button'); 
      } 
      } 
     }, 100); 
    }, 

}; 

當我嘗試從另一個方法調用它(使用this.warpLoop()),我得到:

Uncaught TypeError: Property 'warpLoop' of object #<Object> is not a function 

這是爲什麼?

+0

@dystroy我已經添加了整個對象。 – fredley

+1

您需要閱讀關於'this'如何在Javascript中工作的內容。直到你理解它纔會相當混亂(如果你認爲你理解它,甚至會更加困惑!)。網絡上有很多和很多資源,這是一個非常普遍的問題。 [這將是一個很好的起點](http://stackoverflow.com/questions/3127429/javascript-this-keyword),但如果你搜索它還有很多。 – Spudley

回答

3

在JavaScript的this值沒有詞法定義。它由函數的調用方式來定義。

一個典型的解決方法是的this值存儲在在封閉範圍的變量,然後在內部範圍引用它。

var that = this; 

setTimeout(function() { 
    that.whatever() 
}, 1000) 

同時您還可以結合外this值使用Function.prototype.bind()回調,你似乎有一個.increment()方法未引發錯誤。所以綁定可能會打破。

+0

我試圖改變'warpLoop'採取的參數'self',並通過它雖然 - 蟒蛇的風格,但沒有幫助... – fredley

+0

@TomMedley:不,這不會幫助,除非你定義一個'self'變量來引用對象。基本上,如果你想要的'this'在'warpLoop'的值來引用一個特定的對象,則應該從該對象調用'warpLoop',如在'my_object.warpLoop()'。這就是爲什麼我們保留外部'這個'值在一個變量。 – 2013-05-21 16:11:01

+0

您可以像示例中那樣使用閉包。查看MDN獲取關閉信息。 – HMR

5

這樣的背景下setTimeout的變化,可以用封閉來保持這種背景下。

var test={ 
warpLoop : function(){ 
    var me=this;//set closure to get the right this context 
    setTimeout(function() { 
    console.log("this is:",this); // is window 
    console.log("me is:",me); // is test 
    // can call me.warpLoop() but not this.warpLoop() 
    }, 100); 
} 
} 
test.warpLoop(); 

你的代碼可以是這樣的:

var time = { 

    warps : 3, 
    warpCounter : 3, 

    warp : function(){ 
     if (this.warps > 0){ 
      this.warps--; 
      this.warpLoop = 50; 
      this.warpLoop(); 
     } 
    }, 

    warpLoop : function(){ 
     //the setTimeout calls me.warpCounter not this.warpCounter 
     // wich is the same as window.warpCounter since the next 
     // line is not part of the setTimeout execution you can 
     // use this 
     console.log("warpLoop called,warpCounter is",this.warpCounter); 
     var me=this; 
     setTimeout(function() { 
      //me.increment();    
      if (me.warpCounter--){ 
      me.warpLoop(); 
      }else{ 
      if(me.warps > 0){ 
       //htmlInteraction.enableButton('warp-button'); 
      } 
      } 
     }, 100); 
    }, 

}; 
time.warpLoop(); 
+0

我已經試過,但我仍然得到錯誤,它不是一個功能... – fredley

+0

奇怪的事情是怎麼回事,我可以叫'warpLoop'從物體之外,而不是從內部的另一種方法(我得到錯誤我的問題)。爲什麼是這樣? – fredley

+0

@TomMedley我已經包含了特定於您的情況的代碼。將未發佈的功能註釋掉,因爲這會產生錯誤。 – HMR

相關問題