【问题标题】:ES6 internals of const in for loopsES6 for 循环中的 const 内部结构
【发布时间】:2017-07-20 08:43:36
【问题描述】:

我对 ES6 中 for 循环如何在幕后操作感兴趣。

这是基本示例

var funcs = [];
for (let i = 0; i < 5; i++) {
    funcs.push(function () {
        console.log(i);
    });
};

每个函数都会获得正确的 i 值(从 0 到 4)的原因是因为 let 正在创建 5 个新作用域,并且函数被绑定到它们相应的作用域。这就是我的想法,这对我来说最有意义。如果是这种情况,那么为什么 const 声明 (i) 失败是没有意义的,因为它应该创建 5 个新范围,并且 const 变量可以在不同的范围内愉快地生活。 在 let 之前我们确实使用 IIFE 来达到相同的效果,但是该代码所做的是它基本上为函数创建了新的范围,我认为 let 在幕后做同样的事情。

如果上面的语句不正确,那么一定是 let inside for 循环只创建了一个范围,但我不明白这与 var 声明有何不同以及函数如何获得正确的 i 值。更清楚地说,假设 let 绑定到一个由 for 循环创建的新作用域,并且在这种情况下 var 声明被提升到全局作用域,但这仍然是一个要使用的作用域。

谁能分享一下这个话题?

【问题讨论】:

  • 如果您将i 定义为常量,那么代码将在执行i += 1 时失败,不是吗?
  • 好吧const i 无法工作,因为i++ 试图修改它
  • @Bergi 但 OP 确实有道理。不是每个i 都绑定到新范围内的递增值吗?
  • @ftor 是的,它会 - 如果它没有失败 TypeError: Assignment to constant variable
  • @ftor 猜我得写一个答案

标签: javascript for-loop ecmascript-6 constants


【解决方案1】:

每个函数都会获得正确的 i 值(从 0 到 4)的原因是因为 let 正在创建 5 个新作用域并且函数被绑定到它们对应的作用域。

是的,就是这样。详情见Explanation of `let` and block scoping with for loops(实际上有6个作用域)。

如果是这样,那么为什么 const 声明 (i) 失败就没有意义了,因为它应该创建 5 个新的作用域,而 const 变量可以在不同的作用域中愉快地生活。

您在这里的错误假设是constlet 的工作方式相同。是的,完全有可能在循环体评估中创建 5 个consts。但这对于像

这样的循环来说是没有意义的
for (const i=0; i<5; i++) {
    console.log(i);
}

这将导致TypeError: Assignment to constant variable - 你不能增加const。所以你不应该在for 循环中使用它(注意for…infor…of 循环又是不同的)。

好的,可以写类似的东西

let i=0; for (const j=i; i<5; i++) …

并期望它能够工作并在正文中获得 5 个不同的 const j 变量。但这也不是发生的事情,因为这是一种完全奇怪的写法。如果你想在每次循环迭代中声明const,最好明确地写出来:

for (let i=0; i<5; i++) {
    const j=i;
    …
}

它简洁明了,实际上可以满足您在上面的预期。

for 循环中的 const 声明实际上是如何使用的,可以在此示例中显示:

for (const iterator = {…}; iterator.hasNext(); iterator.step()) {
    … iterator.getValue() …
}

如果我们检查the spec,这实际上与

{
    const iterator = {…};
    for (; iterator.hasNext(); iterator.step()) {
        … iterator.getValue() …
    }
}

这意味着constant 在循环头部被声明一次。在每次迭代中重新声明它是没有意义的,毕竟它的值是恒定的。

【讨论】:

  • 所以虽然技术上可行,但它会与const 的语义相矛盾。这就说得通了。谢谢!
  • 谢谢,他们决定在 for 循环中禁用它是有道理的。
猜你喜欢
  • 2018-02-28
  • 2013-02-03
  • 2015-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多