例子:
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
这个例子的结果是:打印出 6 个 6。
来分析下它的结果:
- 首先:setTimeout() 函数的意思是过一会再执行,在这个例子里,会过一会再打印出 i 的值。显然,for 循环会让 setTimeout() 执行6次,结果会打印6次 i 的值。
- 可为什么6次取的 i 值都是 6,而不是 0,1,2,3,4,5 呢?
这是因为JS的闭包,是先记录“变量名”,等需要用到的时候再去取“变量值” 。 for 循环每执行一次,都有一个 setTimeout() 记录要调用外部变量 i ,但每次只记录变量名为 i 而不取值;for 循环结束后(i = 6),setTimeout() 才去取出外部变量 i 的值。每次 setTimeout() 打印出一个6,故6次 setTimeout() 共打印出6个6 。 - 那为什么for 循环结束了,setTimeout() 才会去取外部变量的值?
简单来说就是:JS是单线程环境,会优先执行完所有的同步任务(如 for 循环),再执行异步任务(for循环每执行一次,会把一个 setTimeout() 插入异步任务队列),因此 for 循环全部结束,才会从任务队列中取出 setTimeout() 来执行。
那么,怎么让它输出0,1,2,3,4,5呢?
可以 for 和 let 配合,let 声明放 for 循环里面:
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}