使用需要参数的非匿名函数的setInterval必须在匿名函数内。为什么?

时间:2012-10-15 11:47:46

标签: javascript jquery

好的我已经在jquery / javascript中查看了有关setInterval的几个帖子和其他地方关于答案的烦人的事情是我不知道解决方案为什么会起作用。

请考虑:

使用匿名函数我们可以设置警报以重复输出“bunnies”:

setInterval(function(){
  alert("bunnies")
},3000);

但是如果我们想要使用非匿名函数,我们必须编码

  

的setInterval(跳,3000);

其中功能:

function hop(){
    alert("bunnies");
}

如果我们尝试编码:

setInterval(hop(),3000);

只执行一次。我不明白为什么会这样。我已经阅读了各种SO,这意味着我们需要传递对setInterval的引用。这是否意味着第一个形式setInterval(hop,3000);通过引用传递。如果是这样可以解释?

因此我们有一个问题。显然,希望能够将参数传递给函数跳像......

setInterval(hop("bunnies"),3000);

其中功能:

function hop(msg){
    alert(msg);
}

这确实会导致调用hop并输出“bunnies”,但该函数再次被调用一次。

因此,我可以解决将参数传递给由setInterval控制的函数的唯一方法是将其合并到匿名函数中:

setInterval(function(){
 hop("bunnies")
},3000);

这传递参数并重复执行跳跃,每隔3秒警告我们一次兔子(非常重要的是警告兔子)。

因此问题:

  1. 这是唯一允许您传入参数的语法。
  2. 为什么setInterval(hop(“bunnies”),3000);不行。

4 个答案:

答案 0 :(得分:13)

setInterval期望函数作为第一个参数。当你尝试:

setInterval(function() {...}, 100);

setInterval(funcName, 100);

您正确传递了一个功能。

然而,当您尝试setInterval(funcName(), 100);时,您实际上是调用该函数并将其返回值传递给setInterval这是不正确的。

答案 1 :(得分:6)

  

为什么setInterval(hop("bunnies"),3000);不起作用。

setInterval(hop("bunnies"),3000);会立即致电hop ,然后将其返回值undefined)传递给setInterval(它将被忽略,因为它不是函数或字符串)。

  

这是唯一允许您传入参数的语法。

不,但它是最受支持的。

另一种语法是

 setInterval(hop, 3000, "bunnies")

答案 2 :(得分:6)

1。这是唯一允许您传递参数的语法吗?

是的,这是我能想到的唯一直接的方式......

setInterval(function(){
    hop("bunnies")
},3000);

...当然,如果你需要处理很多间隔,你可以写一个辅助函数,例如:

function Looper() {
    this.loops = {};
    this.start = function(name, fn, interval, params) {
        this.loops[name] = setInterval(function() {
            fn.apply(null, params);  // maybe bind the function?
        }, interval);
    };
    this.stop = function(name) {
        clearInterval(this.loops[name]);
    };
}

(试一试:http://jsfiddle.net/ceHMs/

你会像这样使用它:

function say(name, msg){ console.log(name,':',msg) };
function shout(name, msg){ console.log(name,':',msg.toUpperCase()) };

var looper = new Looper();
looper.start('say', say, 1000, ['clock' 'tick']);
looper.start('shout', shout, 2000, ['clock' 'tack']);
// ... later ...
looper.stop('shout');

但你必须评估这是否真的有必要。


2。为什么setInterval(hop("bunnies"),3000);不起作用。

这是因为setInterval需要对每隔几毫秒执行一次的Function的引用。

括号是这里的关键。函数名后跟括号确实执行给定的函数而返回函数的结果因此你不会传递引用to setInterval但是函数hop的返回值('bunnies')。 函数的引用只是函数的名称。如果要调用引用的函数,只需在引用中附加括号即可。琐碎的例子:

function executeFunction(fn){
    fn();
};

知道了这一点,我们实际上可以修改你的跳跃函数,使其适用于setInterval(hop("bunnies"),3000);

function hop(msg){
    return function(){ alert(msg) }
}

但这几乎与在setInterval调用中直接使用匿名函数完全相同。现在你只需要在调用hop时返回匿名函数,这会让你的setIntervall调用更短。

最后,它归结为您的个人偏好和具体用例。大多数情况下,直接在setInterval中使用匿名函数的方法是最明显的方法,也是其他人最容易理解的方法。

答案 3 :(得分:1)

你应该将函数作为变量传递而不是调用它。

  

的setInterval(跳,3000);

因为第一个参数是一个按给定间隔调用的函数,所以通过像hop()一样调用函数,而不是传递函数。如果要传递参数,请使用函数包装器

  

的setInterval(函数(){一跳(参数)},3000);