为什么setTimeout需要匿名函数才能工作?

时间:2014-05-13 20:14:21

标签: javascript setinterval

我正在阅读StackOverflow here上的答案,该答案解释了如何使用setTimeout在网页上创建一种重复循环。但是,我想知道为什么setTimeout需要匿名函数才能工作。请考虑以下代码:

trainingTimer(60,0);

function trainingTimer(duration,c) {
    document.getElementById("timer").innerHTML = "Time left: "+(duration-c);
    if(duration==c) {
        alert("Time is up!");
    }
    else {
        window.setTimeout(trainingTimer(duration,c+1),1000);
    }
}

我根据上面链接的答案编写了这个,但是当它运行时,它会立即遍历所有60个trainingTimer个调用,并立即在我的网页上显示“剩余时间:0”。但是,如果我修改

window.setTimeout(trainingTimer(duration,c+1),1000);

并将trainingTimer(duration,c+1)包装在像这样的匿名函数中

window.setTimeout(function() {trainingTimer(duration,c+1)},1000);

然后代码完全正常。

我想知道为什么我必须在匿名函数中包装一个命名函数,以便setInterval正常工作。感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

这个

window.setTimeout(trainingTimer(duration,c+1),1000); 

相同
var result = trainingTimer(duration,c+1);
window.setTimeout(result,1000); 

它获取执行方法的结果并分配它。

因为训练计时器方法什么都不返回。你的代码基本上是这个

trainingTimer(duration,c+1);
window.setTimeout(undefined, 1000); 

答案 1 :(得分:2)

运行时必须在调用函数之前评估传递给任何函数的参数列表。您在此代码中首先传递给setTimeout

window.setTimeout( trainingTimer(duration,c+1), 1000 );

调用函数的结果,而不是函数本身。在函数中包装它可以解决这个问题。

该功能不必是匿名的:

function callTrainingTimer() {
    trainingTimer( duration, c + 1);
}

// ...

window.setTimeout(callTrainingTimer, 1000);

也有效。

答案 2 :(得分:2)

因为setTimeout的工作原理。它的第一个参数是你希望它在x毫秒后运行的函数。

当你这样做时:

window.setTimeout(trainingTimer(duration,c+1),1000);

您正在做的是立即正在运行 trainingTimer,并将其返回值发送到setTimeout

你需要给它一个功能,这就是你做的原因:

window.setTimeout(function() {
    trainingTimer(duration, c+1);
},1000);

是一种没有功能的方法,但它 NOT 推荐

window.setTimeout('trainingTimer(duration,c+1)', 1000);

这将使用eval()来运行代码。这不是传递函数,而是推荐。 eval()不安全,请勿使用。