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

Difference between eval and setTimeout execute string code

本文关键字:执行 字符串 代码 setTimeout 之间 eval      更新时间:2024-04-21

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

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

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

他们是如何在幕后被处决的?

请参阅MDN上的setTimeout参考。

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

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

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

以下是支持它的参考:

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

setTimeout使用的参数比函数引用和超时多。在超时之后输入的任何内容都将作为参数传递给您的函数。

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

在执行此代码时,javascript会假装第3行显示"alert(foo)"。Foo是在函数的作用域中定义的。

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

当执行此代码时,javascript将进入一个新函数;即CCD_ 7。在"新"函数的作用域中,未定义foo

作为正确答案的补充,这里有一个对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/