244

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

例子:

setTimeout("alertMsg()", 3000);

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

我也看到我可以这样做:

setTimeout(alertMsg, 3000);

带括号的是引用,不带括号的是复制。当我使用引号和括号时,它变得疯狂。

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

带括号:

setTimeout("alertMsg()", 3000);

没有引号和括号:

setTimeout(alertMsg, 3000);

第三个是只使用引号:

setTimeout("alertMsg", 3000);

注意:更好的setTimeout参考来源是MDN

4

6 回答 6

384

使用setIntervalsetTimeout

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

  • 匿名函数

    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);

还有另一种方法可以将参数传递给处理程序,但它不是跨浏览器兼容的

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

回调上下文

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

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

安全

尽管有可能,但您不应将字符串传递setTimeoutor setInterval。传递字符串会产生setTimeout()setInterval()使用类似于将字符串作为脚本执行的功能eval()从而使任意且可能有害的脚本执行成为可能。

于 2012-04-25T09:39:08.067 回答
3

我认为您编写的 setTimeout 函数没有运行。如果您使用 jquery,则可以通过执行以下操作使其正确运行:

    function alertMsg() {
      //your func
    }

    $(document).ready(function() {
       setTimeout(alertMsg,3000); 
       // the function you called by setTimeout must not be a string.
    });
于 2012-04-25T09:44:28.017 回答
2

完全同意约瑟夫。

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

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

于 2012-04-25T09:44:02.290 回答
1

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

设置超时( 'string', number)

是在运行时间(经过number几毫秒之后)评估第一个参数的值。基本上等于

设置超时( eval('string'), number)

这是

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

所以你提到的样本不是好的样本,可能会在不同的上下文中给出,或者只是简单的错字。

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

于 2019-04-27T19:19:09.493 回答
0
    ##If i want to wait for some response from server or any action we use setTimeOut.

    functionOne =function(){
    console.info("First");

    setTimeout(()=>{
    console.info("After timeOut 1");
    },5000);
    console.info("only setTimeOut() inside code waiting..");
    }

    functionTwo =function(){
    console.info("second");
    }
    functionOne();
    functionTwo();

## So here console.info("After timeOut 1"); will be executed after time elapsed.
Output:
******************************************************************************* 
First
only setTimeOut() inside code waiting..
second
undefined
After timeOut 1  // executed after time elapsed.
于 2019-07-29T12:20:49.943 回答
-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() 不起作用,因为我们将它放在引号中而没有参与方,因此它被视为字符串。

于 2018-07-19T19:54:46.397 回答