我感兴趣的是如何在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声明在这种情况下被提升到全局范围,但这仍然是一个可以使用的范围。
任何人都可以对这个主题有所了解吗?
答案 0 :(得分:1)
每个函数获得正确的i值(从0到4)的原因是因为let创建了5个新的作用域,函数被绑定到它们相应的作用域。
是的,这就是发生的事情。有关详细信息,请参阅Explanation of `let` and block scoping with for loops(实际上有6个范围)。
如果是这种情况,那么为什么const声明(i)失败是没有意义的,因为它应该创建5个新的范围,而const变量可以在不同的范围内幸福地生活。
这里的错误假设是const
与let
的作用相同。是的,完全可以在循环体评估中创建5 const
个。但这对于像
for (const i=0; i<5; i++) {
console.log(i);
}
会导致TypeError: Assignment to constant variable
- 您无法增加const
。因此,您不应在for
循环中使用它(请注意for…in
和for…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
蚂蚁在循环的头部被声明一次。无论如何,在它的所有值都是常量之后,在每次迭代中重新声明它都没有意义。