本文将使用一个例子简单地讨论一下函数的调用时机
函数的调用时机不同,结果也不同
首先查看 setTimeout文档
打印666666
为什么以下函数打印出6个6?
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
} // out: 6, 6, 6, 6, 6, 6
由于setTimeout会在一段时间以后再执行其内部的函数,所以在跳出循环以后也就是1 === 6
时打印 i 的值,即打印6个6
那么怎样让以上代码打印出 0,1,2,3,4,5 呢?
打印012345
只需将 let 换个位置
for(let i = 0; i<6; i++){ // let 到这里来了
setTimeout(()=>{
console.log(i)
},0)
} // out: 0, 1, 2, 3, 4, 5, 6
因为 let 申明的变量是局部作用域,每次循环都是一个新的作用域,就会开辟一个新的空间让 i 指向它,之前的空间得不到释放,形成了闭包,在跳出循环体以后,打印的是之前每个循环中 i 曾经指向的值,等价于
{
let i = 0;
setTimeout(()=>{
console.log(i)
},0)
}
{
let i = 1
setTimeout(()=>{
console.log(i)
},0)
}
// ...
还是打印012345
使用立即执行函数
let i = 0
for(i = 0; i<6; i++){
!function(j){
setTimeout(()=>{
console.log(j)
},0)
}(i)
} // out: 0, 1, 2, 3, 4, 5, 6