我知道eval
和setTimeout
都可以接受字符串作为(第一个)参数,我知道我最好不要使用它。我只是好奇为什么会有区别:
!function() {
var foo = 123;
eval("alert(foo)");
}();
!function() {
var foo = 123;
setTimeout("alert(foo)", 0);
}();
第一个会起作用,第二个会出错:foo is not defined
他们如何在幕后执行?
答案 0 :(得分:5)
请参阅reference of setTimeout
on MDN。
在全局上下文中计算字符串文字,因此当字符串被计算为代码时,调用setTimeout()的上下文中的局部符号将不可用。
相反,传递给eval()的字符串文字是在调用eval的上下文中执行的。
答案 1 :(得分:2)
setTimeout的eval
还在全局范围内执行,因此它不知道foo
。
这是支持reference:
字符串文字在全局上下文中进行评估,因此是本地符号 在调用setTimeout()的上下文中将不可用 当字符串被评估为代码时。
答案 2 :(得分:1)
setTimeout比函数引用和超时需要更多参数。超过超时的任何内容都将作为参数传递给您的函数。
setTimeout(myFunction(param1, param2), 0, param1, param2);
答案 3 :(得分:0)
!function() {
var foo = 123;
eval("alert(foo)");
}();
执行此代码时,javascript会假装第3行显示“alert(foo)”。 Foo在函数范围内定义。
!function() {
var foo = 123;
setTimeout("alert(foo)", 0);
}();
执行此代码时,javascript将进入新功能;即function() {alert(foo)}
。在“新”函数的范围内,未定义foo
。
答案 4 :(得分:0)
作为正确答案的补充,这里是对eval
的调用,它会给你相同的行为,并在这种情况下出错:
!function() {
var foo = 123;
window.eval("alert(foo)"); // <- note the window.eval, this is important and changes the behavior of the `eval` function
}();
!function() {
var foo = 123;
setTimeout("alert(foo)", 0);
}();
此博客文章详细介绍了不同类型的eval
:http://perfectionkills.com/global-eval-what-are-the-options/