2 回答
![?](http://img1.sycdn.imooc.com/545868cd00013bbb02200220-100-100.jpg)
TA贡献1942条经验 获得超3个赞
var 有函数作用域。
let 具有块作用域。
所以,在这样的for循环中:
for (let i = 0; i < row.length; i++)
循环的每次迭代都有它自己的单独i变量。当在循环内使用异步操作时,每个单独的i变量都有自己的异步回调,因此一个不会覆盖另一个。
由于var是函数作用域,当你这样做时:
for (var i = 0; i < row.length; i++)
i整个函数中只有一个变量,for循环的每次迭代都使用相同的变量。for循环的第二次迭代改变i了第一次迭代中任何异步操作可能试图使用的值。如果这些异步操作试图i在异步回调中使用它们的值,这for可能会给这些异步操作带来问题,因为同时循环已经改变了它。
这是一个经典的例子:
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 10);
}
而且,现在与 let
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 10);
}
运行每一个并查看结果的差异。在这两个示例中,for循环运行到完成并安排了 5 个计时器。在这个var例子中,所有的计时器回调都看到了i现在完成的for循环中的一个变量,因此它们都输出5为 的值i。
在这个let例子中,循环的每次迭代都有它自己的i变量,它不受for循环行进的影响,所以当他们的定时器回调被调用时(for循环完成后),它们仍然具有与i迭代时相同的值的for循环最初执行的,因此它们的输出越来越多的预期序列。
![?](http://img1.sycdn.imooc.com/545847aa0001063202200220-100-100.jpg)
TA贡献1828条经验 获得超13个赞
添加回答
举报