我知道 let 具有 block 作用域,而 var 具有功能作用域。但是我不明白在这种情况下,使用 let 将如何解决问题
const arr = [1,2,3,4];
for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(arr[i])
}, 1000);
} // Prints undefined 5 times
const arr = [1,2,3,4];
for (let i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(arr[i])
}, 1000);
} // Prints all the values correctly
这都跟变量的作用域有关。让我们尝试将这两个部分包装成函数,并观察输出:
function test() {
// `i` will be declared here, making it a non-for-loop scoped variable
const arr = [1, 2, 3, 4];
for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(arr[i])
}, 1000);
} // Prints undefined 5 times
}
test();
所以在第一种情况下,i
会被提升,并且由于setTimeout
的异步特性,i
会立即变成4循环结束而无需等待。这将使 arr[i]
指向数组中的 undefined
元素。
在第二种情况下,i
没有被提升,并且对循环的每次迭代都有范围访问,使 i
准确地可用于 console.log
声明。因此结果符合预期:
function test() {
const arr = [1, 2, 3, 4];
for (let i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(arr[i])
}, 1000);
} // Prints all the values correctly
}
test();