【问题标题】:Is it legal to use variables in a closure before declaring them with let or const in an outer scope?在外部范围内用 let 或 const 声明变量之前在闭包中使用变量是否合法?
【发布时间】:2016-03-27 09:48:09
【问题描述】:

如下所示的一段代码在 Firefox 和 Chrome 中都能完美运行。

function A() {
    console.log(message);
}

let B = function () {
    console.log(message);
};

let message = 'Hello, World!';

A();
B();

无论如何,JSHint 抱怨在声明之前使用了 message 变量。

'message' 在声明之前使用,这对于 'let' 变量是非法的。

当声明跟随闭包块时,在闭包内的外部作用域中使用用 let 或 const 声明的变量真的是非法的,还是 JSHint 疯了?

【问题讨论】:

  • 不知道否决票,但这里是a bit of MDN that is relevant
  • 可能,AB 可以在分配给 message 之前被调用,在这种情况下你确实会得到一个错误。
  • @FelixKling 是的。无论如何,如果 AB 在分配给 message 之前被调用,但在其定义之后,则不会发生错误。

标签: javascript closures ecmascript-6


【解决方案1】:

在您的情况下,使用let 定义的变量很好。但在其他情况下,它会导致问题。例如,

console.log(x); let x = 10; 

会给你一个参考错误。因为x 已创建但未初始化。这不像使用var 的普通变量定义。 let 声明不会是 initialized,直到带有 let 的语句被执行。因此,JSHint 以一种通用的方式向您抱怨您的代码。

【讨论】:

  • letconst 也被提升了,但它们没有初始化,因此出现错误。
  • @FelixKling 感谢您指出我对此的误解。你能指点我一个相关的链接吗?它抛出了参考错误,所以我就是这样想的。 letconst 的提升情况如何?
  • ecma-international.org/ecma-262/6.0/…。步骤 27c 为 var 声明创建绑定并使用 undefined 初始化它们。步骤 35 为 letconst 创建绑定,但不初始化它们。你也可以这样测试它:let foo = 42; { console.log(foo); let foo = 21; }。这仍然会引发引用错误,因为内部声明会遮盖外部声明,但它尚未初始化。
  • @FelixKling 再次感谢。说真的,我现在从你那里学到了很多东西。 :) 编辑了我的帖子。
  • 总是乐于提供帮助:)
猜你喜欢
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
  • 2017-12-02
  • 2018-10-14
  • 2021-04-12
相关资源
最近更新 更多