这里用let 声明的i 有块级作用域,for循环了四次就是生成了4个块级作用域,每个块级作用域里的i分别为 0 1 2 3,每个定时器里面的i也是用的每个作用域里的i,所以能正常打印出 0 1 2 3
for (let i = 0; i < 4; i++) {
// console.log(i);
setTimeout(() => {
console.log(i); //0 1 2 3
}, 1000)
}
console.log('全局' + i); //报错
但是用var 声明的i是被挂载到全局作用域上的,定时器里的i用的都是window.i,所以当定时器执行里面的函数的时候,for循环已经结束,i==4了,所以打印出来的结果是4 4 4 4
for (var i = 0; i < 4; i++) {
// console.log(i);
setTimeout(() => {
console.log(i); //4 4 4 4
}, 1000)
}
//这个全局4会被最先打印出来
console.log('全局' + i); //4
如何用var的时候也要达到正常输出的效果呢?可以在定时器外面在套一层函数,也就是将定时器放入一个函数作用域里面,因为函数里面的变量都不会被挂载到全局上
for (var i = 0; i < 4; i++) {
(function fn(a) {
setTimeout(() => {
console.log(a); //0 1 2 3
}, 1000)
})(i) //这里将for循环里的i赋值给fn()里面的a,也就是a 来保存i的值
// console.log(i);
}
//这个全局4会被最先打印出来
console.log('全局' + i); //4