当将函数传递给方法时,为什么使用匿名函数容器而不仅仅是原始函数有效

When passing functions to a method, why does using an anonymous function container work and not just the original function?

本文关键字:函数 不仅仅是 有效 原始 为什么 方法      更新时间:2023-09-26

我是JavaScript的新手,一直在处理递归计时事件。以下只是在新的行上打印倒计时上的下一个数字,直到达到limit。jsfiddle上的一个版本。

function countdown(limit,initial,period){
    if (initial>=limit){
        document.getElementById('tag').innerHTML += '<br/>'+initial;
        window.setTimeout(function(){countdown(limit,--initial,period);},period);
    }
};

上面的代码确实有效,但我最初写它的方式是用这一行:

window.setTimeout(function(){countdown(limit,--initial,period);},period);

Kust喜欢这个:

window.setTimeout(countdown(limit,--initial,period),period);

不起作用。为什么必须将函数countdown()封装在function(){}中?这是最好的方法吗?为什么我最初尝试的方式不起作用?

谢谢!

这是最好的方法。window.setTimeout期望函数作为其第一个参数。

window.setTimeout(function(){countdown(limit,--initial,period);},period);

正在将匿名函数作为第一个参数传递给setTimeout。

window.setTimeout(countdown(limit,--initial,period),period);

正在将执行的函数倒计时的结果作为第一个参数传递给setTimeout。在您的情况下,倒计时的结果总是undefined

为了进一步说明,您还可以向window.setTimeout传递一个函数,如下所示:

var myFunc = function(){countdown(limit,--initial,period);};
window.setTimeout(myFunc, period);

setTimeout的第一个参数应该是一个函数。当你写

window.setTimeout(countdown(limit,--initial,period),period);

首先调用函数。它返回undefined。这类似于调用

window.setTimeout(undefined,period);

所以,是的,把你的倒计时包装成function(){},这是最好的方式。

setTimeout接受函数或代码(到eval)。你的countdown是一个函数,但

countdown(limit,--initial,period)

是函数调用结果,它将是undefined,因为它什么都不返回。因此,第二个版本可以简化为

window.setTimeout(undefined, period)

这显然是行不通的。

虽然所有其他答案都很好,并解释了为什么调用countdown(...)函数的第二种方法不起作用,但我想补充一点,您并不局限于将countdown(...)封装到匿名函数中。您也可以使用Function的绑定方法,如下所示:

window.setTimeout(countdown.bind(null, limit,--initial,period),period);

这里的第一个参数是函数的作用域(因为在countdown(...)中没有引用this,所以可以安全地将其设置为null)。如果您有任何问题,请查看链接上的文档。