let i = 0
for( i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
// 输出6个'6'
setTimeOut需要浏览器提供的计时器线程来计时,属于异步任务。JavaScript属于单线程语言,将setTimeOut交给浏览器计时后,自己会转到执行主线程的代码,即上面例子中的for循环,当循环执行完成后,读取异步消息队列里的任务setTimeOut,由于全局定义了一个i,所以此时,i = 6,共有6个setTimeOut,输出6个6
for( let i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
//输出 0,1,2,3,4,5
此时看上去也只是定义了一个i,为啥输出结果会不一样?
因为
JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量
i时,就在上一轮循环的基础上进行计算。
这个是JavaScript底层实现的,类似于
let i = 0
if( 0 < 6 ){
let k = i; // 底层实现
setTimeout(()=>{
console.log(k)
},0)
}
i++;
if( 1 < 6 ){
let k = i;
setTimeout(()=>{
console.log(k)
},0)
}
除了在for循环中使用let定义变量,还可以用闭包实现输出0-5
let i;
for( i = 0; i < 6; i++){
function fn(i){
setTimeout(()=>{
console.log(i)
},0)
}
fn(i)
}