带有和不带引号和括号的setTimeout之间的区别

问题描述 投票:231回答:5

我正在学习JavaScript,最近我学到了关于JavaScript计时事件的知识。当我在setTimeout学习W3Schools时,我注意到一个奇怪的人物,我之前没有遇到过。他们使用双引号然后调用该函数。

例:

setTimeout("alertMsg()", 3000);

我知道JavaScript中的双引号和单引号表示字符串。

我也看到我可以这样做:

setTimeout(alertMsg, 3000);

用括号表示,没有括号,它被复制。当我使用引号和括号时,它变得疯狂。

如果有人能向我解释这三种使用setTimeout的方式之间的区别,我将很高兴:

括号:

setTimeout("alertMsg()", 3000);

没有引号和括号:

setTimeout(alertMsg, 3000);

第三个是仅使用引号:

setTimeout("alertMsg", 3000);

N.B。:setTimeout参考的更好的来源是MDN

javascript settimeout
5个回答
375
投票

使用setIntervalsetTimeout

您应该将对函数的引用作为setTimeoutsetInterval的第一个参数传递。该引用可以采用以下形式:

  • 一个匿名函数 setTimeout(function(){/* Look mah! No name! */},2000);
  • 现有函数的名称 function foo(){...} setTimeout(foo, 2000);
  • 指向现有函数的变量 var foo = function(){...}; setTimeout(foo, 2000); 请注意,我将“函数中的变量”与“函数名称”分开设置。变量和函数名称占用相同的命名空间并且可以互相破坏,这一点并不明显。

传递参数

要调用函数并传递参数,可以在分配给定时器的回调中调用函数:

setTimeout(function(){
  foo(arg1, arg2, ...argN);
}, 1000);

还有另一种方法可以将参数传递给处理程序,但是it's not cross-browser compatible

setTimeout(foo, 2000, arg1, arg2, ...argN);

回调上下文

默认情况下,执行时回调的上下文(定时器调用的函数内的this的值)是全局对象window。如果您想更改它,请使用bind

setTimeout(function(){
  this === YOUR_CONTEXT; // true
}.bind(YOUR_CONTEXT), 2000);

安全

虽然有可能,你应该not pass a stringsetTimeoutsetInterval。传递一个字符串使setTimeout()setInterval()使用类似于eval()的功能executes strings as scripts,使任意和可能有害的脚本执行成为可能。


3
投票

我认为你写的setTimeout函数没有运行。如果你使用jquery,你可以通过这样做使它正确运行:

    function alertMsg() {
      //your func
    }

    $(document).ready(function() {
       setTimeout(alertMsg,3000); 
       // the function you called by setTimeout must not be a string.
    });

2
投票

完全同意约瑟夫。

这是测试这个的小提琴:http://jsfiddle.net/nicocube/63s2s/

在小提琴的上下文中,字符串参数不起作用,在我看来,因为函数没有在全局范围中定义。


0
投票

如果您将字符串作为函数的第一个参数传递,实际情况会发生什么

的setTimeout('string'number

是在运行时(在numberof miliseconds通过之后)评估的第一个参数的值。基本上它等于

setTimeout(eval('string')number

这是

一种替代语法,允许您包含字符串而不是函数,该函数在计时器到期时编译和执行。建议不要使用此语法,原因与使用eval()存在安全风险的原因相同。

因此,您提到的样本不是好样本,可能会在不同的背景下或仅仅是简单的拼写错误。

如果你像这样调用setTimeout(something, number),第一个参数不是字符串,而是指向一个名为something的东西。再次,如果something是字符串 - 那么它将被评估。但如果它是函数,那么函数将被执行。 jsbin sample


-1
投票

括号:

setTimeout("alertMsg()", 3000); // It work, here it treat as a function

没有引号和括号:

setTimeout(alertMsg, 3000); // It also work, here it treat as a function

第三个是仅使用引号:

setTimeout("alertMsg", 3000); // It not work, here it treat as a string

function alertMsg1() {
        alert("message 1");
    }
    function alertMsg2() {
        alert("message 2");
    }
    function alertMsg3() {
        alert("message 3");
    }
    function alertMsg4() {
        alert("message 4");
    }

    // this work after 2 second
    setTimeout(alertMsg1, 2000);

    // This work immediately
    setTimeout(alertMsg2(), 4000);

    // this fail
    setTimeout('alertMsg3', 6000);

    // this work after 8second
    setTimeout('alertMsg4()', 8000);

在上面的示例中,第一个alertMsg2()函数立即调用(我们给出时间4S但不打扰)在alertMsg1()(等待2秒的时间)之后然后alertMsg4()(等待8秒的时间)但是alertMsg3()不起作用,因为我们将它放在没有派对的引号内,因此它被视为字符串。

© www.soinside.com 2019 - 2024. All rights reserved.