1

JS 函数的调用时机

  • 函数的要素:
  1. 调用时机:JS函数的不同执行时机,会影响到函数运行的输出结果,不能通过代码本身百分百判断函数输出什么,而是要根据函数具体的执行时机。
  2. 作用域:每个函数都会默认创建一个作用域
  3. 闭包:JS函数会就近寻找最近的变量
  4. 形式参数
  5. 返回值
  6. 调用栈:进入一个函数的时候,要先把环境存下来,才能进去,有的东西越多,需要一个数组来保存,那保存的环境所在的数组叫做调用栈
  7. 函数提升
  8. arguments(除了箭头函数)
  9. this(除了箭头函数)

*调用时机:时机不同,结果就不同

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

输出:
image

关于setTimeout

  • 用于在指定的毫秒数后调用函数或计算表达式;
  • 意思就是尽快执行,而不是马上执行;
  • 可以理解为做完手头的事稍后再执行。

举例说明setTimeout,比如小明正在玩游戏,但是妈妈喊小明吃饭,这时小明setTimeout回答好的,但是手上的游戏仍持续一段时间后,才执行console.log去吃饭这个动作。

解释: 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)
}

输出:
image

方法二:利用 const 关键字

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

image

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

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

image


keiko
1 声望0 粉丝