JS 函数的执行时机

181 阅读2分钟

JS 函数的执行时机

什么是函数的执行时机呢,下面举一个例子来讲

let a = 1
  function f(){
      console.log(a)
  }
f()
a = 22
//打印出了1,很好理解,虽然a又重新赋值了,但却是在执行函数之后,所以函数打印出了1
let a = 1
  function f(){
      console.log(a)
  }
  a = 22
f()
//出打印出了22,这也很好理解,在函数运行前,又给a重新赋值,函数打印出来重新赋值的a

上边这两个例子能表达一个简单的执行时机,在执行函数前,未给变量重新赋值,执行函数得到的返回值就时一开始的赋值,如果在执行函数之前我们更改了赋值,那么函数的返回值就是我们更改的值,


这里我们加入一个定时器setTimeout()函数,( JavaScript 提供定时执行代码的功能)

还是原来的例子,我们加入定时器

let a = 1
  function f(){
  setTimeout(()=>{
      console.log(a)
    },0)
  }
  a = 22
f()
//出打印出了22,这也很好理解,在函数运行前,又给a重新赋值,函数打印出来重新赋值的a
let a = 1
  function f(){
  setTimeout(()=>{
      console.log(a)
    },0)
  }
f()
a = 22
//还是出打印出了22,

这是因为setTimeout函数就是在过一段时间执行,至于过多长时间我们不深究,但在这段时间内,我们的a已经重新赋值了,所以执行函数得到的是一个22.


下面举一个经典的面试题:

let i = 0
for(i = 0 ;i < 5;i++){
    console.log(i)
}//打印出了0,1,2,3,4

下面我们加上定时器

let i = 0
for(i = 0 ;i < 5;i++){
setTimeout(()=>{
    console.log(i)
    },0)
}//打印出了5个5,

打印出5的原因是因为执行到i=4的时候进入的循环,当i=5的时候不符合i<5,跳出了循环,虽然跳出循环但此时的i的值就是5,所以打印出5;

至于打印5次5,因为let在全局声明了i的值,i在进入循环的5次后最终的值为5.所以打印出了5次5,

怎样才可以打印出1,2,3,4呢?我们知道let是一个遵循块作用域的声明,所以我们可以将声明放在里面,

for(let i = 0;i < 5;i++){
    setTimeout(()=>{
    console.log(i)
    },0)
}//这样就可以打印出1,2,3,4,

我们也可以在里面加入const声明

let i = 0
for( i = 0;i < 5;i++){
   const x = i
    setTimeout(()=>{
    console.log(x) 
    },0)
}//同样我们可以打出0,1,2,3,4

我们在块作用域内声明一个变量x,x的值等于i,所以会有6次i的值复制给x,所以定时器执行时,会打印出5个值,(第六次不符合循环,跳出,但x的值等于i=5)


以上只是个人理解,有问题望指正。