JavaScript函数 - 执行时机

任务队列
变量作用域
异步&同步
闭包Closure

先看一段代码。

1
2
3
4
5
6
let i = 0
for(i = 0; i < 6; ++i){
setTimeout(()=>{
console.log(i)
},0)
}

setTimeout函数会在指定时间到达后执行给定的函数,或代码段。
setTimeout添加的执行任务是异步的,每执行一次就往任务队列添加一次指定任务。只有主线程上的代码全部执行完才会执行任务队列里的任务,所以当主线程for循环执行完之后 i 的值为6,这个时候再去任务队列中执行任务,i全部为6;

1
2
3
4
5
6
let i = 0
for(i = 0; i < 6; ++i){
setTimeout(()=>{
console.log(i)
},0)
}
1
2
3
4
5
6
6
6
6
6

想要输出结果为0,1,2,3,4,5。可以在代码中构建闭包Closure,将变量i的生命周期延长。

1
2
3
4
5
for(let i = 0; i < 6; ++i){
setTimeout(()=>{
console.log(i)
},0)
}
1
2
3
4
5
6
7
var i;
for(i = 0; i < 6; ++i){
let j = i
setTimeout(()=>{
console.log(j)
},0)
}
1
2
3
4
5
6
7
// Output
0
1
2
3
4
5

也可以通过函数参数传递会拷贝变量的原理。
修改给setTimeout的函数,并在调用前传递参数。

1
2
3
4
5
6
var i;
for(i = 0; i < 6; ++i){
setTimeout((i)=>{
console.log(i)
},0,i)
}
1
2
3
4
5
6
7
// Output
0
1
2
3
4
5

JavaScript函数 - 执行时机
http://example.com/2023/01/08/JavaScript函数的执行时机/
作者
Ray
发布于
2023年1月8日
许可协议