我正在学习 JavaScript,最近学习了 JavaScript 计时事件。当我在
W3Schools了解到
setTimeout
时,我注意到一个我以前没有遇到过的奇怪人物。他们使用双引号,然后调用该函数。
示例:
setTimeout("alertMsg()", 3000);
我知道 JavaScript 中的双引号和单引号表示字符串。
我还看到我可以这样做:
setTimeout(alertMsg, 3000);
带括号的为引用,不带括号的为复制。当我使用引号和括号时,它变得疯狂。
如果有人能向我解释这三种使用方式之间的区别,我会很高兴
setTimeout
:
带括号:
setTimeout("alertMsg()", 3000);
没有引号和括号:
setTimeout(alertMsg, 3000);
第三个仅使用引号:
setTimeout("alertMsg", 3000);
注意:
setTimeout
的更好参考来源是 MDN。
setInterval
或 setTimeout
您应该传递对函数的引用作为
setTimeout
或 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);
尽管这是可能的,但您不应该将字符串传递给
setTimeout
或setInterval
。传递字符串使 setTimeout()
或 setInterval()
使用类似于 eval()
的功能,将字符串作为脚本执行,从而使任意且可能有害的脚本执行成为可能。
完全同意约瑟夫的观点。
这里有一个小提琴来测试这个:http://jsfiddle.net/nicocube/63s2s/
在小提琴的上下文中,字符串参数不起作用,在我看来,因为该函数未在全局范围内定义。
我认为您编写的 setTimeout 函数没有运行。 如果你使用jquery,你可以通过这样做使其正确运行:
function alertMsg() {
//your func
}
$(document).ready(function() {
setTimeout(alertMsg,3000);
// the function you called by setTimeout must not be a string.
});
如果您将字符串作为函数的第一个参数传递,实际会发生什么
设置超时(
,'string'
)number
是在运行时评估的第一个参数的值(经过
number
毫秒后)。
基本上等于
设置超时(
,eval('string')
)number
这是
另一种语法,允许您包含字符串而不是函数,该函数在计时器到期时编译并执行。不建议使用此语法,原因与使用 eval() 存在安全风险相同。
因此,您引用的示例不是好的示例,可能是在不同的上下文中给出的,或者只是简单的拼写错误。
如果你像这样调用
setTimeout(something, number)
,第一个参数不是字符串,而是指向一个叫做something
的东西的指针。再次,如果 something
是字符串 - 那么它将被评估。但如果是函数,那么函数就会被执行。
jsbin 示例
##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.
不管怎样,我发现了 setTimeout 函数的另一个怪癖:
setTimeout(myFunction(),10000); // executes immediately!!
setTimeout('myFunction()',10000); // executes in 10 seconds
带括号:
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()(A 时间等待 2 秒)然后alertMsg4()(时间等待 8 秒)但是 AlertMsg3() 不起作用,因为我们将其放在引号内 没有派对,因此它被视为字符串。