为什么eval无法访问with语句下的作用域变量?

Cri*_*hez 7 javascript eval with-statement

为什么不能evalwith语句下使用范围变量?

例如:

(function (obj) { 
   with (obj) {
      console.log(a); // prints out obj.a
      eval("console.log(a)"); // ReferenceError: a is not defined
   }
})({ a: "hello" })
Run Code Online (Sandbox Code Playgroud)

编辑:正如知识渊博的CMS所指出的,这似乎是一个浏览器错误(使用WebKit控制台的浏览器).

如果有人想知道我试图提出什么憎恶,那将需要"邪恶" evalwith- 我试图看看我是否可以获得一个函数(用作回调)在另一个上下文中执行而不是它被定义为.不,我可能(咳)不会在任何地方使用它...比任何事都更好奇.

(function (context,fn) { 
    with (context) 
       eval("("+fn+")()"); 
})({ a: "hello there" }, function () { console.log(a); })
Run Code Online (Sandbox Code Playgroud)

CMS*_*CMS 6

这是一个只能从WebKit的控制台重现的错误,它在eval从a调用时绑定调用者上下文时出现问题FunctionExpression.

当进行直接调用时eval,您期望的评估代码应共享变量环境:

(function (arg) {
  return eval('arg');
})('foo');
// should return 'foo', throws a ReferenceError from the WebKit console
Run Code Online (Sandbox Code Playgroud)

还有词汇环境:

(function () {
  eval('var localVar = "test"');
})();

typeof localVar; // should be 'undefined', returns 'string' on the Console
Run Code Online (Sandbox Code Playgroud)

在上面的函数localVar应该在调用者的词法环境中声明,而不是在全局上下文中声明.

对于FunctionDeclarations,行为是完全正常的,如果我们尝试:

function test1(arg) {
  return eval('arg');
}
test1('foo'); // properly returns 'foo' on the WebKit console
Run Code Online (Sandbox Code Playgroud)

function test2() {
  eval('var localVarTest = "test"');
}
test2();
typeof localVarTest; // correctly returns 'undefined'
Run Code Online (Sandbox Code Playgroud)

我能够在Windows Vista SP2上运行的以下浏览器上重现该问题:

  • Chrome 5.0.375.125
  • Chrome 6.0.472.25 dev
  • Safari 5.0.1
  • WebKit Nightly Build r64893