Javascript Google Chrome上的ReferenceError,但Firefox上没有(浏览器错误?)

Javascript Google Chrome上的ReferenceError,但Firefox上没有(浏览器错误?),javascript,google-chrome,referenceerror,Javascript,Google Chrome,Referenceerror,这段代码 eval(` 设a=0; 函数f(){} 函数g(){a;} 控制台日志(f); `); 在严格模式外尚不支持块作用域声明(let、const、函数、类) 调整您的示例可以看到发生了什么,虽然命令有点矛盾,但它看起来像一个bug。将a定义为一个函数,并记录它而不是f,然后查看控制台。您将看到一个闭包是用a、f和g创建的。因为a在g中被引用,并且f和g应该彼此可见,所以这有点道理。但是eval在全球范围内起作用。因此,当您尝试访问它们时,您将无法定义它们。好像这个闭包不能从任何地方访问

这段代码

eval(`
设a=0;
函数f(){}
函数g(){a;}
控制台日志(f);
`);
在严格模式外尚不支持块作用域声明(let、const、函数、类)


调整您的示例可以看到发生了什么,虽然命令有点矛盾,但它看起来像一个bug。将a定义为一个函数,并记录它而不是f,然后查看控制台。您将看到一个闭包是用a、f和g创建的。因为a在g中被引用,并且f和g应该彼此可见,所以这有点道理。但是eval在全球范围内起作用。因此,当您尝试访问它们时,您将无法定义它们。好像这个闭包不能从任何地方访问

尝试:

您将在控制台中看到:

<function scope>
    Closure
        a: function()
        f: function f()
        g: function g()

关闭
a:函数()
f:函数f()
g:函数g()
您的所有其他案例使情况更清楚,并防止问题发生:

  • 未使用eval:范围不匹配不太明显
  • eval中的代码被{}包围:变量是链接的 通过块范围
  • g中未引用a:如果变量 没有链接
  • let更改为var:全局范围内的var在 全球范围。所以不需要关闭
  • 在代码之前添加“使用严格”:在评估中使用严格 要添加到全局范围的变量,因此再次“更容易”地 手柄let与全局函数之间不存在不匹配
看起来像是一个好主意!一个更简单的测试用例是

eval(`
    var f;
    let a;
    ()=>a
`);
f;

变量作用域声明(包括顶级函数声明)没有正确地从非严格的
eval
调用中提升出来,而调用也有一个非平凡的词法声明。

let
在草率模式下受支持,因为根据Chrome 49.0。
<function scope>
    Closure
        a: function()
        f: function f()
        g: function g()
eval(`
    var f;
    let a;
    ()=>a
`);
f;