这是 Chrome 错误还是我使用“use strict”和 eval 无效?

Posted

技术标签:

【中文标题】这是 Chrome 错误还是我使用“use strict”和 eval 无效?【英文标题】:Is this a Chrome bug or is my use of "use strict" and eval invalid? 【发布时间】:2014-10-15 00:17:55 【问题描述】:

此代码在除 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' in Webpack时遇到了它。

【问题讨论】:

您的小提琴设置为使用 jsFiddle 的非常令人惊讶的默认,将您的所有代码包装在 window.onload 处理程序中。 (左侧的第二个下拉菜单。)如果您将其关闭,代码(在全局范围内)将按预期工作:jsfiddle.net/rokkkjcs/2 我也在不使用 jsFiddle 的情况下验证了这一点(以防 jsFiddle 做一些奇怪的事情) .所以这就引出了一个问题:为什么 eval 是在函数内发生还是在全局范围内发生重要?无论哪种方式,test 应该关闭 outer... V. v. 怪异的。 哦,我有没有提到当你直接从控制台的 REPL 运行它时它可以工作(即使包装在一个函数中)?越来越好奇...... 使用 eval 在政治上是不正确的。 @frenchie 你知道我为什么要使用它吗? 【参考方案1】:

为了简化问题: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/

【讨论】:

我不太确定我理解你的意思。您是否声称您的示例与我的示例相同?你能解释一下为什么吗? 唯一的问题是使用eval() 向周围范围添加一个新变量。在严格模式下,该变量将不可用。它可以在没有包装的情况下工作,因为它在全局范围内。 但是 eval 不是在严格模式下执行的,是吗?【参考方案2】:

实际上 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

【讨论】:

以上是关于这是 Chrome 错误还是我使用“use strict”和 eval 无效?的主要内容,如果未能解决你的问题,请参考以下文章

Chrome 似乎报告了错误的错误行

Chrome:输入文本元素在复制/粘贴后失去垂直对齐

Chrome 不透明度过渡错误

Chrome开发工具服务工作者错误图标/计数

语法错误或default_popup - chrome扩展名

铬错误? CSS3 列在每个新列上都有一个额外的空间