【发布时间】:2013-10-14 10:14:06
【问题描述】:
我了解eval() 在非严格环境中的工作方式,但是在严格模式下使用eval() 的情况完全让我感到困惑。在全局范围内直接调用eval() 时,变量会保存在新的eval() 范围内:
'use strict';
eval('var a = 1;');
console.log(a); // ReferenceError: a is not defined
但是,如果我在全局范围内对 eval() 执行 间接 调用(应该是同一件事,对吗?),它的行为就好像它不是在严格模式下(如果你不信,看this JSFiddle):
'use strict';
(0, eval)('var a = 1;'); // indirect call to eval
console.log(a); // 1???
如需了解(0, eval) 的作用,请参阅Why does google main page use (0, obj.func)(args) syntax?。
至少根据我对eval() 应该如何在严格模式下工作的理解,它意味着(无论是直接调用还是间接调用eval())为@987654334 中定义的变量创建一个新范围@call,但是这里似乎并非如此。 (ECMA-262 规范第 5 版10.4.2)
所有主流浏览器(包括 Internet Explorer 10、Chrome 30 和 Firefox 24)都是这种情况,所以我认为这不是错误。他们不是都打算做同样的事情吗?如果不是,为什么会这样?
注意:是的,我知道使用eval() 的“危险”——我只是想了解这背后的逻辑:)
【问题讨论】:
-
对我来说就像一个错误。你是如何执行上面的代码的?哪个浏览器/JS 解释器?
-
@AaronDigulla:在给定的 JSFiddle 中,Chrome 30。
-
@AaronDigulla:Firefox 24 和 IE10 也表现出这种行为。
-
好问题。正在努力:) 不过有人可能会打败我。
-
Safari 6、webkit nightly 和 opera 也是如此。
标签: javascript eval ecmascript-5