我有一个简单的javascript类。
此类的一个方法使用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);
}
答案 0 :(得分:36)
setInterval可以直接使用函数,而不仅仅是字符串。 https://developer.mozilla.org/en/DOM/window.setInterval
即
loadingTimer = setInterval(showLoading, 100);
但是,为了获得最佳的浏览器兼容性,您应该使用带有显式引用的闭包:
var t = this;
loadingTimer = setInterval(function(){t.showLoading();}, 100);
答案 1 :(得分:19)
loadingTimer = setInterval("this.showLoading()", 100);
首先,不要将字符串参数用于setInterval / Timeout。它与使用eval
的方式相同,并且可能同样在将来因CSP安全限制而失败。所以相反:
loadingTimer = setInterval(this.showLoading, 100);
但是,正如您所说,这将失去所有者引用,因此被调用的函数将看不到正确的this
。在将来(新定义的ECMAScript第五版),您将能够使用function.bind
将该函数绑定到其所有者:
loadingTimer = setInterval(this.showLoading.bind(this), 100);
如果您自己为尚未拥有它的浏览器实施function.bind
(请参阅this answer的底部),您今天就可以使用此语法。
否则,您将需要使用显式闭包,例如刚刚发布的计算机语言学家。
答案 2 :(得分:2)
以上所有答案均可接受。我只是想补充一点,this
的绑定也可以通过使用箭头函数来解决。例如,它们彼此相等。但是,使用箭头功能时,将保持词汇范围:
// Arrow function - my preferred method
loadingTimer = setInterval(() => this.showLoading, 100);
// .bind method
loadingTimer = setInterval(this.showLoading.bind(this), 100);
// Other method
var t = this;
loadingTimer = setInterval(function(){t.showLoading();}, 100);
希望这会有所帮助:D