Javascript eval和setTimeout执行字符串代码之间的差异

Javascript eval和setTimeout执行字符串代码之间的差异,javascript,Javascript,我知道eval和setTimeout都可以接受字符串作为(第1个)参数,我知道最好不要使用这个参数。我只是好奇为什么会有区别: !function() { var foo = 123; eval("alert(foo)"); }(); !function() { var foo = 123; setTimeout("alert(foo)", 0); }(); 第一个会起作用,第二个会给出一个错误:foo未定义 他们是如何在幕后执行的 setTimeout的ev

我知道
eval
setTimeout
都可以接受字符串作为(第1个)参数,我知道最好不要使用这个参数。我只是好奇为什么会有区别:

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

!function() {
    var foo = 123;
    setTimeout("alert(foo)", 0);
}();
第一个会起作用,第二个会给出一个错误:
foo未定义


他们是如何在幕后执行的

setTimeout的
eval
是在全局范围内额外执行的,因此它不知道
foo

下面是一个备份:

字符串文字是在全局上下文中计算的,因此本地符号 在调用setTimeout()的上下文中,将不可用 当字符串作为代码计算时

字符串文本在全局上下文中求值,因此当字符串作为代码求值时,调用setTimeout()的上下文中的本地符号将不可用

相反,传递给的字符串文本是在调用eval的上下文中执行的

!function() {
    var foo = 123;
    eval("alert(foo)");
}();
当执行此代码时,javascript将假装第3行显示“警报(foo)”。Foo是在函数的作用域中定义的

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

执行此代码时,javascript将输入一个新函数;即
function(){alert(foo)}
。在该“新”函数的作用域中,未定义
foo

setTimeout使用的参数多于函数引用和超时。输入的任何超过超时的内容都将作为参数传递给函数

setTimeout(myFunction(param1, param2), 0, param1, param2);

作为对正确答案的补充,下面是对
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);
}();
!函数(){
var-foo=123;

window.eval(“alert(foo)”;//在调用setTimeout回调之前foo是否超出范围?为什么要处理邪恶的东西^^^不要使用这两个:)一个有趣的相关视图。传递给
eval
的代码将在执行
eval
的上下文中执行?确切地说,字符串文字是“就地”计算的并且可以访问在该上下文中定义的变量。@wong2实际上这取决于如何调用
eval
。在现代浏览器中,以下eval是全局范围的:因为它是间接eval。下面是间接eval调用的更多示例