Google Chrome 上的 ReferenceError 但 Firefox 上没有(浏览器错误?)
Posted
技术标签:
【中文标题】Google Chrome 上的 ReferenceError 但 Firefox 上没有(浏览器错误?)【英文标题】:ReferenceError on Google Chrome but not on Firefox (Browser Bug?) 【发布时间】:2016-12-19 16:56:12 【问题描述】:这段代码
eval(`
let a = 0;
function f()
function g() a;
console.log(f);
`);
在 Firefox 48.0 上运行良好,而在 Google Chrome 52.0.2743.116(64 位)上导致 Uncaught ReferenceError: f is not defined
。
如果
eval
未使用,或
eval
内的代码被
包围,或者
a
未在 g
中引用,或者
let
改为var
,或
代码前加"use strict"
这里发生了什么?
【问题讨论】:
【参考方案1】:调整您的示例,您可以看到发生了什么,虽然命令有点矛盾,但它看起来像一个错误。将 a 定义为函数并记录它而不是 f,然后查看控制台。您会看到使用 a、f 和 g 创建了一个闭包。由于 a 在 g 中被引用,并且 f 和 g 应该是彼此可见的,所以有点意思。但是 eval 在全局范围内有效。因此,当您尝试访问它们时,您会得到未定义的信息。就像这个闭包不能从任何地方访问一样。
试试:
eval('let a = function(); function f() ;function g()a;;console.dir(a);');
你会在控制台中看到这个:
<function scope>
Closure
a: function()
f: function f()
g: function g()
您的所有其他案例使情况更加清晰,并防止问题发生:
没有使用eval:范围不匹配不太明显, eval 内的代码用 括起来:变量是相互关联的 通过块范围。 g 中没有引用 a:如果变量没有需要闭包 没有关联。 let 改为 var:全局范围内的 var 定义在 全球范围。所以不需要关闭 在代码前添加“use strict”:use strict in eval 防止 要添加到全局范围的变量,因此再次“更容易” 处理。 let 需要与全局函数链接之间没有不匹配。【讨论】:
【参考方案2】:eval(`
"use strict";
let a = 0;
console.log(f);
function f()
function g()
a;
`);
在严格模式之外尚不支持块范围的声明(let、const、函数、类)
【讨论】:
let
根据MDN,自 Chrome 49.0 起支持草率模式。【参考方案3】:
看起来是a novel V8 bug!一个更小的测试用例是
eval(`
var f;
let a;
()=>a
`);
f;
当调用还具有重要的词法声明时,变量范围的声明(包括***函数声明)没有从非严格的 eval
调用中正确提升。
【讨论】:
以上是关于Google Chrome 上的 ReferenceError 但 Firefox 上没有(浏览器错误?)的主要内容,如果未能解决你的问题,请参考以下文章
Google webfonts 在 Windows 上的 Chrome 中呈现断断续续
window.open 用于 Google 地图 - iPhone 上的灰屏 Google Chrome
Chrome 上的 Google Auth API Javascript idpiframe 初始化错误