Javascript:如何清除非全局(封闭)setTimeout?

Posted

技术标签:

【中文标题】Javascript:如何清除非全局(封闭)setTimeout?【英文标题】:Javascript: How to clear a non-global (closured) setTimeout? 【发布时间】:2011-08-20 23:15:07 【问题描述】:

我正在努力成为一个好公民,并尽可能远离全球范围。有没有办法访问不在全局范围内的 setTimeout 变量?

那么,在这个例子中,有人会如何取消“计时器”?

myObject.timedAction = (function()
    var timer;
        return function()
            // do stuff

            // then wait & repeat       
            timer = setTimeout(myObject.timedAction,1000);
        ;
)();

我已经尝试过clearTimeout(myObject.timedAction.timer,1000);(没有成功),不知道还能尝试什么。

【问题讨论】:

【参考方案1】:

除非您有对timer 的引用,否则您不能这样做,因为您将其声明为范围内的变量。您可以执行以下操作:

myObject.timedAction = (function()
    return function()
        // do stuff

        // then wait & repeat       
        myObject.timedAction.timer = setTimeout(myObject.timedAction,1000);
    ;
)();

clearTimeout(myObject.timedAction.timer);

请注意,上面的代码将只允许一个计时器。如果您需要引用多个计时器,则需要对其进行调整。

【讨论】:

【参考方案2】:

关键是内部变量是私有的,外部世界无法访问。所以你必须稍微改变你的方法:

myObject.timedAction = (function()
    var timer;
    var result = function()
        // do stuff
        // then wait & repeat       
        timer = setTimeout(myObject.timedAction,1000);
    ;

    result.cancel = function() 
        clearTimeout(timer);
    ;

    return result;
)();

myObject.timedAction();       // start it
myObject.timedAction.cancel() // end it

所以现在只能从闭包内部访问计时器。是的,你可以为函数添加方法,因为 JS 很棒。

【讨论】:

哇,“方法”和“功能”在同一个句子里。 @TomalakGeretkai 记住一个函数继承自Object。所以它只是一个对象。【参考方案3】:

将计时器句柄放在对象的属性中:

myObject.timedAction = function()
  // do stuff
  // then wait & repeat
  this.timer = window.setTimeout(function() myObject.timedAction(); ,1000);
;

请注意,您应该将来自计时器的调用包装在一个函数中,以便将其作为对象的方法而不是作为全局函数调用,否则您将无法使用this 访问您的对象。

现在您可以使用以下方法停止计时器:

window.clearTimeout(myObject.timer);

【讨论】:

以上是关于Javascript:如何清除非全局(封闭)setTimeout?的主要内容,如果未能解决你的问题,请参考以下文章

javascript如何列出全局对象的非原生属性。

javascript如何列出全局对象的非原生属性。

JS封闭函数闭包内置对象

javascript如何列出全局对象的非原生属性

JavaScript中的“闭包”

如何清除或删除 Julia 中的全局变量?