ES6 for循环中的内部结构

时间:2017-07-20 08:43:36

标签: javascript for-loop ecmascript-6 const constants

我感兴趣的是如何在ES6的幕后操作循环。

这是基本的例子

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

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

如果上面的语句不正确,那么必须让for循环内部只创建一个范围但是我不知道如何与var声明不同以及函数如何获得正确的值。为了使它更加清晰,让我们说let绑定到一个由for循环创建的新范围,var声明在这种情况下被提升到全局范围,但这仍然是一个可以使用的范围。

任何人都可以对这个主题有所了解吗?

1 个答案:

答案 0 :(得分:1)

  

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

是的,这就是发生的事情。有关详细信息,请参阅Explanation of `let` and block scoping with for loops(实际上有6个范围)。

  

如果是这种情况,那么为什么const声明(i)失败是没有意义的,因为它应该创建5个新的范围,而const变量可以在不同的范围内幸福地生活。

这里的错误假设是constlet的作用相同。是的,完全可以在循环体评估中创建5 const个。但这对于像

这样的循环来说没有意义
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;
    …
}

干净清晰,实际上可以达到您的预期目标。

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

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

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

具有相同的效果
{
    const iterator = {…};
    for (; iterator.hasNext(); iterator.step()) {
        … iterator.getValue() …
    }
}

这意味着const蚂蚁在循环的头部被声明一次。无论如何,在它的所有值都是常量之后,在每次迭代中重新声明它都没有意义。