在JavaScript中使用setTimeout()和setInterval()时调用函数

Calling a function when using setTimeout() and setInterval() in JavaScript

本文关键字:setInterval 调用 函数 JavaScript setTimeout      更新时间:2023-09-26

如果我使用setTimeout()和setInterval()调用命名函数,没有括号,它会按预期工作。当我用括号调用同一个函数时,它要么立即执行,要么给出一个错误。

我正在寻找一个更深入的了解在这个问题上,然后我发现在网上。你们能给我解释一下为什么是这样吗?

var func = function(){
    console.log("Bowties are cool.");
}
setTimeout(func(), 1500);
// Prints "Bowties are cool." immediately
setInterval(func(), 1500);
// Throws an error
setInterval(func, 1500);
// Works as expected
setTimeout(console.log("Bowties are cool."),1500);
// This method has the same result as "setTimeout(func(), 1500)".

必须传递一个函数引用给setTimeout()setInterval()。这意味着你传递一个函数名后没有(),或者你传递一个匿名函数。

当您在func()的函数名后面包含()时,您立即执行该函数,然后将返回结果传递给setInterval()setTimeout()。除非函数本身返回另一个函数引用,否则这永远不会达到您想要的效果。对于Javascript程序员来说,这是一个非常常见的错误(我自己在学习这门语言时也犯过同样的错误)。

所以,正确的代码是:
setTimeout(func, 1500);
setInterval(func, 1500);

如果你知道其他使用指针的语言,你可以把一个函数的名字和后面的()想象成一个指向函数的指针,这就是Javascript中的函数引用,当你希望它能够在以后执行一些函数时,这就是你传递给函数的东西,而不是立即。


当你错误地这样做时:

setTimeout(func(), 1500);
setInterval(func(), 1500);

它立即执行func(),然后将返回结果传递给setTimeout()setInterval()。因为你的func()不返回任何东西,你基本上是这样做的:

func();
setTimeout(undefined, 1500);

这是你观察到的,而不是你想要的。


此外,如果您想执行特定的函数调用,例如console.log("Bowties are cool."),那么您可以将其包装在另一个函数中,如下所示:

setTimeout(function() {
    console.log("Bowties are cool.")
}, 1500);

所以,你再次传递一个函数引用到setTimeout(),可以稍后执行,而不是立即执行,这是你正在做的。

setTimeout和setInterval期望传递给它们一个函数引用。你不应该在setTimeout和setInterval调用中调用这个函数。

错误(不要这样):

setTimeout(func(), 1500);
setInterval(func(), 1500);
setTimeout(console.log("Bowties are cool."), 1500);
setInterval(console.log("Bowties are cool."), 1500);

正确的:

setTimeout(func, 1500);
setInterval(func, 1500);
setTimeout(function() {
    console.log("Bowties are cool.");
}, 1500);
setInterval(function() {
    console.log("Bowties are cool.");
}, 1500);

注意我是如何将console.log包装在一个匿名函数中,以便与setInterval和setTimeout一起使用。我不能将console.log传递给setInterval和setTimeout函数,因为它需要参数"Bowties are cool."。将它封装在匿名函数中解决了这个问题。

当您在定义的函数后添加括号时,实际上是在调用或调用该函数。

但是当你把一个函数作为参数传递给另一个函数时,你不想调用这个函数,你只想把这个函数的引用作为参数传递给它,(你传入的函数,在需要的时候可以调用)

有关回调函数的更多信息,请参见这里。