JS函数执行时机的认识
分类:javascript
我们看下面的代码下面的案列:
- 为什么如下代码会打印6个6? 而不是我们感觉上的应该打印的 0,1,2,3,4,5,6
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
为了解释上面的代码:
- 首先要知道JavaScript是单线程语言,所以JavaScript执行任务的时候是一行一行执行的.
- 但是新闻包含的超清图片加载很慢,难道我们的网页要一直卡着直到图片完全显示出来?
- 因此我有可以把任务分为两类:
- 同步任务
- 异步任务
- 这里不详细说明上面的概念.你只要知道
setTimeout
是JavaScript中的基础异步函数,这个函数可以改变函数的执行顺序. - setTimeout()方法设置一个定时器,该定时器在定时器到期后执行一个函数或指定的一段代码。
- 根据上面说的,可以知道,
setTimeout
是异步的,需要等待同步执行完成在执行console.log(i)
,
所以当for循环执行完成后, i
的值就是6,然后在执行性setTimeout
,当然是执行6次,结果就是6个6.
怎么才能输出 0 , 1, 2, 3, 4, 5呢?
- 把let写在for循环里面,这样就单纯的为每个
i
创建一个块级作用域,也就是复制6个i
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
- setTimeout 的第三个参数 写i 容易混淆改成了X
- setTimeout的第三个参数每次传最新的值给setTimeout
x
- setTimeout的第三个参数每次传最新的值给setTimeout
let i = 0
for(i = 0; i<6; i++){
setTimeout((x)=>{
console.log(x)
},0,i)
}
3.立即执行函数
- 这里的(i)
给function(x)传了值
let i = 0
for(i = 0; i<6; i++){
!function(x){
setTimeout(()=>{
console.log(x)
},0)
}(i)
}