《JS 函数的执行时机》
以例子说明
让我们先来看一段代码
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
上面这段代码console.log(i)会打印出什么?
答: 会打印出6个6
为什么会打印出6个6呢?
答: 关于setTimeout
- 用于在指定的毫秒数后调用函数或计算表达式;
- 意思就是尽快执行,而不是马上执行;
- 可以理解为做完手头的事稍后再执行。
解释: setTimeout是一个异步任务,执行到这里的操作会被浏览器丢到另一个任务队列里去, 浏览器这时候会继续执行for循环。每一次for循环的时候,setTimeout都执行一次,但是里面的函数没有被执行,而是被放到了任务队列里面,等待执行,for循环了6次,就放了6次,当主线程执行完成后,才进入任务队列里面执行。这时候因为for循环i=6了,所以输出的全部都是6。
如何理解异步呢?
异步代码不等待结果,直接进行下面的代码,所以定时器只是开启了,而没有立即执行里面的代码,等到当前运行坏境的代码执行完之后再回来执行定时器里面的代码。总结:异步就是不等待结果的代码。
由于setTimeout的原因,将原本要即时打印的结果延迟到for循环结束之后,所以这里结果是for循环结束才开始打印执行的,且只有1个i,i的值已经是5,再执行i++。
所以连续打印了6个6。
写出让上面代码打印出0,1,2,3,4,5的方法
方法一
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
由于JS才for和let一起用时,会加东西,每次循环会多创建一个i,
所以会打印出0,1,2,3,4,5
方法二
利用const关键字
let i = 0
for(i = 0; i < 6; i++){
const x = i
setTimeout(()=>{
console.log(x)
})
}
方法三
利用setTimeout的第三个参数,将i传进去
let i = 0
for(i = 0; i < 6; i++){
setTimeout((value)=>{
console.log(value)
},0,i)
}