一、为什么如下代码会打印 6 个 6 ?
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
答:因为调用时机,setTimeout会先把所有代码执行,for循环结束后才会打印结果。
二、写出让上面代码打印 0、1、2、3、4、5 的方法
答:让for挟持let使用,每次循环会创建一个‘ i ’再打印结果。
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
三、除了for let 配合,还有什么其他方法可以打印出 0、1、2、3、4、5 ?
答:
(1)闭包
通过闭包,将 i 的变量驻留在内存中,当输出a时,引用的是外部函数A的变量值 i,i 的值是根据循环来的,执行setTimeout时就可以确定里面的输出。
for(var i=0;i<6;i++){
! function(i){
setTimeout(()=>{ console.log(i) },1000)
}(i) //在匿名函数后加 ( )立即执行,并把 i 当作参数 value传入匿名函数循环执行,参数 i 和匿名函数组成了闭包
}
原理:
声明匿名函数 function(value){} 包裹 setTimeout()
然后在匿名函数前加上运算符‘ !’,防止生成新的全局变量(避免污染全局)
在匿名函数后加个()立即调用,并把 i 当作参数 value 传入匿名函数进行调用
(2)利用 setTimeout 的第三个参数,将 i 传进去
由于每次传入的参数是从for循环里面取到的值,所以会依次输出0~5,简单一句话:setTimeout的第三个参数作用,它就是当作setTimeout第一个函数的参数。
let i
for(i = 0; i<6; i++){
setTimeout((value)=>{
console.log(value)
},0,i) //setTimeout 第三个参数,声明后这个参数可以将自身传给第一个参数 function(value),
}
原理:
使用setTimeout 的第三个参数--这个参数可以将自身传给第一个参数
也就是匿名函数function(value)中,作为所需要的参数value,value可默认不写
而 i 共传入6次(0,1,2,3,4,5),通过匿名函数即可打印出
通常不写第三个三处,如果默认不写第三个参数,则不会传入函数