2010-01-04 34 views
20

我有一個簡單的JavaScript類。通過setInterval事件調用類原型方法

該類的一個方法使用setInterval函數設置一個計時器。每次事件觸發時,我想要調用的方法都是在同一個類中定義的。

問題是,我該如何將此方法作爲參數傳遞給setInterval函數?

一次嘗試是setInterval('this.showLoading(),100)。但不起作用。這個方法訪問類的屬性,所以我需要'this'引用。

這是示例代碼:

function LoadingPicture(Id) 
    { 
     this.imgArray = null; 
     this.currentImg = 0; 
     this.elementId = Id; 
     this.loadingTimer = null; 
    } 


    LoadingPicture.prototype.showLoading = function() 
    { 
     if(this.currentImg == imgArray.length) 
      currentImg = 0; 

     document.getElementById(this.elementId).src = imgArray[this.currentImg++].src; 
    } 


    LoadingPicture.prototype.StartLoading = function() 
    { 
     document.getElementById(this.elementId).style.visibility = "visible"; 
     loadingTimer = setInterval("showLoading()", 100); 
    } 

回答

31

的setInterval可以直接採取的函數,而不是隻是一個字符串。 https://developer.mozilla.org/en/DOM/window.setInterval

loadingTimer = setInterval(showLoading, 100); 

但是,爲了獲得最佳的瀏覽器兼容性,你應該使用一個封閉與明確提到:

var t = this; 
loadingTimer = setInterval(function(){t.showLoading();}, 100); 
+1

後一種方法更普遍適用。 +1 – xtofl 2010-01-04 20:25:16

+0

是的,取決於...我認爲前者在AS3中工作,但我不記得它是否在JS中跨瀏覽器。後者通常是最安全的。 – 2010-01-04 20:27:08

+0

像魅力一樣工作 – Andres 2010-01-04 20:31:00

14
loadingTimer = setInterval("this.showLoading()", 100); 

首先,不要使用字符串參數的setInterval /超時。這與使用eval的方式相同,在未來可能會出現CSP安全限制。因此,而不是:

loadingTimer = setInterval(this.showLoading, 100); 

然而,正如你說,這將失去業主參考,因此被調用函數將看不到正確的this。在未來(新定義的ECMAScript第五版),你就可以到功能綁定到其擁有者function.bind

loadingTimer = setInterval(this.showLoading.bind(this), 100); 

,如果你實現自己function.bind對於還沒有它的瀏覽器(見this answer的底部),你今天可以使用這種語法。

否則,您將需要使用顯式閉包,如剛纔發佈的示例計算機語言學習者。