let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
for执行的结果是输出6,6,6,6,6,6
为什么上面的代码会打印 6 个 6,这是因为setTimeout()
是异步执行,即使delay
值取的为0,也只是意味着“马上”执行,或者尽快执行。所以它会在for循环结束之后执行,此时变量i
的值已经被覆盖为6
了,所以会执行6次console.log(6)
,得到结果就是6,6,6,6,6,6
如何让以上代码打印出0--5
在for循环表达式中使用let声明表达式变量
可以将代码改成以下方式:
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
此时for执行的结果是输出0,1,2,3,4,5
因为let有自己的作用域块,所以在for循环表达式中使用let其实就等价于在代码块中使用let,也就是说:
1.for( let i = 0; i< 5; i++) 这句话的圆括号之间,有一个隐藏的作用域。
2.for( let i = 0; i< 5; i++) { 循环体 } 在每次执行循环体之前,JS 引擎会把 i 在循环体的上下文中重新声明及初始化一次。
类似于:
{
// 父块作用域
let i = 0;
// 第一次循环
{
// 子块作用域,将i传进来,并进行形参赋值(相当于有形参i的函数自执行)
let i = 0; // 这里`JavaScript`引擎帮我们传入实参,并进行形参赋值
setTimeout(() => console.log(i), 0);
}
i++;
// 第二次循环
{
let i = 1;
setTimeout(() => console.log(i), 0);
}
// ...
}
此时就会输出0,1,2,3,4,5
还有一种方式可以打印出0--5
let i=0
for(i = 0; i<6; i++){
setTimeout((value)=>{
console.log(value)
},0,i)
}
把i作为参数传入到setTimeout中即可实现打印出0--5了。
网友评论