2010-01-04 94 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的底部),你今天可以使用这种语法。

否则,您将需要使用显式闭包,如刚才发布的示例计算机语言学习者。