JS 函数的执行时机

108 阅读2分钟

函数执行的时机不同,结果则不同

看以下几个例子:

let a = 1 function fn(){
    console.log(a)
}

上面代码中,没有打印,因为函数都没有调用

let a = 1
function fn(){
  console.log(a)
}
a = 2
fn()
// 结果:2

上面代码中,在调用函数之前重新进行赋值,所以打印 '2'

let a = 1
function fn(){
  console.log(a)
}

fn()
a = 2
// 结果:1

上面代码中,我们先调用的函数再赋值,所以打印 '1'

从上面几个例子就可以看出函数调用的时机也非常重要,时机不同,结果则不同

let a = 1
function fn(){
    setTimeout(()=>{
        console.log(a)
    },0)
}
fn()
a = 2
// 结果:2

上面代码为什么后赋值又可以呢, setTimeout 作用:稍后执行 ,那稍后是什么时候呢,是忙完当前事情之后,例如上面代码,在调用函数,等 a = 2 忙完之后在运行函数,所以打印结果为 '2' 。

再看一个例子:

let i = 0
for( i = 0; i<6; i++){
    setTimeout(()=>{
        console.log(i)
    },0)
}
// 结果:6个6

上面代码同样的道理,setTimeout 稍后执行,等 for 循环忙完了在打印,循环结束之后 i = 6 ,所以会打印 6 个 6 。

如何正常打印出 0 , 1 , 2 , 3 , 4 , 5

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

为什么又可以了呢,对比上个例子,这次 let i = 0 我们是在 for 循环内部声明,for循环 和 let 一起使用时,每经过一次循环就会多创建一个 'i' ,复制了 6 个 'i' 。

方法二:

利用 setTimeout 的第三个参数,将 i 传进去

let i = 0
for(i = 0; i<6; i++){
    setTimeout((value)=>{
      console.log(value)
    },0,i)
}

方法三:

利用 const 常量 ,常量的值是无法(通过重新赋值)改变的,也不能被重新声明

let i = 0
for(i = 0; i<6; i++){
    const x = i
    setTimeout(()=>{
      console.log(x)
    })
}