Javascript 通过setInterval事件调用类原型方法

Javascript 通过setInterval事件调用类原型方法,javascript,Javascript,我有一个简单的javascript类 此类的一个方法使用setInterval函数设置计时器。每次触发事件时要调用的方法是在同一个类中定义的 问题是,如何将此方法作为参数传递给setInterval函数 一次尝试是setInterval('this.showLoading(),100)。但是不起作用。此方法访问类属性,因此我需要“This”引用 这是示例代码: function LoadingPicture(Id) { this.imgArray = null;

我有一个简单的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);
    }

setInterval可以直接接受函数,而不仅仅是字符串。

i、 e

但是,为了实现最佳浏览器兼容性,您应该使用带有显式引用的闭包:

 var t = this;
 loadingTimer = setInterval(function(){t.showLoading();}, 100);
首先,不要使用字符串参数来设置间隔/超时。它与使用
eval
的方法一样狡猾,并且在将来可能会因CSP安全限制而失败。因此:

loadingTimer = setInterval(this.showLoading, 100);
但是,正如您所说,这将丢失所有者引用,因此被调用的函数将看不到正确的
this
。将来(新定义的ECMAScript第五版),您将能够使用
函数将函数绑定到其所有者。bind

loadingTimer = setInterval(this.showLoading.bind(this), 100);
如果您为尚未实现
function.bind的浏览器自己实现了
function.bind(请参见的底部),您现在就可以使用这种语法


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

以上所有答案都是可以接受的。我只是想补充一点,
this
的绑定也可以通过使用箭头函数来解决。例如,这些都是等价的。但是,在使用箭头函数时,词法范围会保持不变:

//箭头函数-我的首选方法
loadingTimer=setInterval(()=>this.showLoading,100);
//.bind方法
loadingTimer=setInterval(this.showLoading.bind(this),100);
//其他方法
var t=这个;
loadingTimer=setInterval(函数(){t.showLoading();},100);

希望这有帮助:D

后一种方法更普遍适用+1是的,视情况而定。。。我认为前者在AS3中有效,但我不记得它在JS中是否跨浏览器。后者通常是最安全的。我倾向于调用变量
that
。如:var that=this;:)
loadingTimer = setInterval(this.showLoading, 100);
loadingTimer = setInterval(this.showLoading.bind(this), 100);