【问题标题】:const variable not hoisted for immediately invoked function没有为立即调用的函数提升 const 变量
【发布时间】:2015-08-09 07:20:50
【问题描述】:

我在玩新的 ECMASCRIPT-6 const 关键字。我不理解关键字的一种特定行为。

假设我有两个功能

第一种情况

(function(){
  console.log(_t); 
  const _t=10;
})();

第二种情况

function t(){
  console.log(_y); 
  const _y=11;
}
t();

对于第一种情况,输出是(不明白为什么)

ReferenceError: 在初始化之前无法访问词法声明 `_t'

对于第二种情况,输出是(很好)

未定义

第二种情况的输出符合预期,但我不知道为什么第一种情况的结果会引发错误。从错误中可以推断出变量没有被提升。但为什么?我发现here const 使用block scope。它与这个范围界定有什么关系吗?

我正在使用 Firefox 开发者版控制台运行测试。

【问题讨论】:

  • 你遇到了temporal dead zone,它还没有完全跨浏览器实现。
  • 请参阅Are variables declared with let or const not hoisted in ES6?,了解它应该如何工作。我无法解释第二种行为 - 对我来说似乎是一个错误。
  • 您是否在外部范围内定义了任何_y(在其他运行的代码中),当您在干净的环境中仅运行这两个sn-ps时会发生同样的事情吗?

标签: javascript scope constants ecmascript-6 hoisting


【解决方案1】:

这是here中提到的F​​irefox相关问题

Firefox 特定说明

const 声明早在 const 出现在 ECMAScript 6 规范中之前就已经在 Firefox 中实现了。有关 const ES6 合规性,请参阅错误 950547 和错误 611388。

从 Gecko 36(Firefox 36 / Thunderbird 36 / SeaMonkey 2.33)开始:

{const a=1};a 现在抛出一个 ReferenceError 并且由于块作用域而不再返回 1。 常量一个;现在抛出一个 SyntaxError ("missing = in const declaration"): 需要一个初始化器。 常数 a = 1; a = 2;现在还会抛出一个 SyntaxError(“对 const a 的赋值无效”)。

我还发现了 here 的东西

我认为 Firefox 引擎对 const 提升非常严格。

我认为这是有道理的。

【讨论】:

  • 这是有道理的。但这应该适用于这两种情况。在吊装期间,仅吊装声明。并且{const a; a=1} 抛出SyantaxError。但这两种类型的函数声明都应该是这种情况。是的,你是对的。这只发生在 Firefox 上。 Chrome 不会抛出任何异常。
  • 我没有解释为什么函数声明和 IEFE 的行为(严格的 ES6 或一些草率的遗留物)不同?
【解决方案2】:

当我在 Firefox (38.0.1) 中尝试时,两者都收到相同的错误消息;它在初始化之前无法访问它。这是有道理的,因为唯一的区别是有一个函数表达式和一个函数声明。

常量标识符实际上是被提升的,这就是为什么你在初始化之前得到无法访问的错误。

在这种情况下,块范围和功能范围是相同的,因为功能代码块是您拥有的唯一块。

如果你添加了一个代码块,当你使用它时常量超出范围,你会得到错误消息“ReferenceError: _y is not defined”:

function t(){
  {
    const _y = 11;
  }
  console.log(_y); // _y is out of scope
}
t();

【讨论】:

    猜你喜欢
    • 2020-05-31
    • 2015-03-25
    • 2016-02-24
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    相关资源
    最近更新 更多