为什么打印出6个6
let i = 0;
for (i = 0; i < 6; i++) {
setTimeout(() => {
console.log(i);
}, 0);
}
原因:在JS执行过程中,当同步代码和异步代码同时存在时,异步代码会在同步代码全部执行完成后再调用。setTimeout是异步代码(就算延迟为0也是异步),它会在代码最后执行。循环结束后,共有6个setTimeout,i通过自增已经变成了6,此时执行6个setTimeout, 把i打出来,就得到6个6.
如何修改才能打印出1,2,3,4,5
-
let与for结合,利用let形成的块级作用域for (let i = 0; i < 6; i++) { setTimeout(() => { console.log(i); }, 0); }原因:每次进入循环, i的值都是当前块级作用域的i, 代码显示如下:
(let i = 0) { setTimeout(()=>{ console.log(i) },0) } (let i = 1) { setTimeout(()=>{ console.log(i) },0) } (let i = 2) { ... -
利用
IIFE(立即调用的函数表达式)let i = 0; for(i = 0; i < 6; i++) { !function(j) { setTimeout(() => { console.log(j) }, 0) }(i); }原因:利用立即执行函数和闭包实现的。每一次循环立即调用的函数表达式得到的都是当前的
i,这样内部函数就调用外部变量形成闭包,setTimeout执行时打印出的值就是当前立即执行函数拿到的i。