2012-07-27 83 views
5

我知道evalsetTimeout既可以接受一个字符串作为(1日)参数,而且我知道,我最好不要用这个。我只是好奇,为什么是有区别:执行字符串代码

!function() { 
    var foo = 123; 
    eval("alert(foo)"); 
}(); 

!function() { 
    var foo = 123; 
    setTimeout("alert(foo)", 0); 
}(); 

第一会的工作,第二个会给出错误:foo is not defined

他们是如何在幕后执行?

+1

不富走出去的范围setTimeout的回调之前被调用? – 2012-07-27 08:57:55

+1

为什么与邪恶的东西搞乱^^不要使用其中任一:) – Andreas 2012-07-27 09:03:06

+0

一个有趣的相关观点[这里](https://stackoverflow.com/q/3492015/465053)。 – RBT 2017-10-07 09:21:44

回答

4

reference of setTimeout on MDN

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

相反,传递给eval()字符串文字在调用EVAL的上下文中执行。

+0

并且传递给'eval'的代码将在'eval'执行的上下文中执行? – wong2 2012-07-27 09:03:29

+0

准确地说,字符串字面值是“就地”评估的并且可以访问在该上下文中定义的变量。 – Wolfram 2012-07-27 09:05:02

+0

@ wong2其实它取决于你如何调用'eval'。在现代浏览器中,以下eval在全局范围内:http://jsfiddle.net/4p9QY/,因为它是间接评估。这里有更多间接评估的例子http://perfectionkills.com/global-eval-what-are-the-options/#indirect_eval_call_examples – Esailija 2012-07-27 09:40:42

2

的setTimeout的eval在全球范围内追加执行的,所以它不知道foo

这里的reference对其进行备份:

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

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未定义。

1

的setTimeout需要比函数参照和超时多个参数。超时输入的任何内容都将作为参数传递给您的函数。

setTimeout(myFunction(param1, param2), 0, param1, param2); 
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); 
}(); 

这个博客后接着在深度上不同类型的evalhttp://perfectionkills.com/global-eval-what-are-the-options/