11

此代码在除 Chrome 之外的所有浏览器中都可以正常工作:

eval("var outer = 0; function test() {'use strict'; outer = 1; } test(); alert('ok');");

(在jsfiddle上试试)。

我所做的只是在上下文中从'use strict'函数中引用外部变量。eval铬 说

Uncaught ReferenceError: outer is not defined 

注意:我最初devtool: 'eval'在 Webpack中使用时遇到过它。

4

2 回答 2

3

为了简化问题:http: //jsfiddle.net/rokkkjcs/6/

eval("var outer=0;");
function test() {'use strict'; outer = 1; } 
test(); 
alert('ok');

解释是:

非严格代码可以使用 'eval' 函数将新变量添加到周围范围。在浏览器支持原生 JSON 之前,“eval”通常(且不安全)用于从字符串构造对象。然后,构建的对象成为周围范围的一部分。在严格模式下,'eval' 不能引入新变量。在严格模式下执行时,以下代码不会将“bar”变量引入周围范围。注意:如果包含 'eval' 的函数在严格模式下执行,则 'eval' 函数内的代码也会在严格模式下执行。

更多信息:http ://cjihrig.com/blog/javascripts-strict-mode-and-why-you-should-use-it/

于 2014-08-21T11:47:20.340 回答
1

实际上 eval 在定义它的范围内创建变量或修改变量,无论您是否使用 val。或者换句话说,默认情况下它没有自己的范围。

所以当你这样做时

eval("var outer = 0;");
console.log(outer); //0

您在外部范围内创建变量。令人惊讶的是,这在 chrome 中也以相同的方式工作 - 是否使用 window.onload 并不重要。

要使 eval 具有自己的范围,您必须执行以下操作:

eval("'use strict'; var outer = 0;"); 
console.log(outer); //Uncaught ReferenceError: outer is not defined 

现在有一个单独的 eval 范围。在 eval 中使用“use strict”,您的代码将在 chrome 中工作,并且不允许覆盖 eval 之外的变量。

eval("'use strict'; var outer = 0; function test() {'use strict'; outer = 1; } test(); alert('ok');");

所以这部分回答了如何避免错误。

第二部分我很感兴趣,但自己找不到答案。

问题如下,为什么你的代码在 chrome 中抛出错误,而这在 chrome 中有效(这意味着创建了全局变量):

window.onload = function() {
   eval("var outer = 0; function test(){console.log(outer); } test();");
}

以及为什么它只发生在window.onload.

于 2014-08-21T12:34:25.260 回答