JS 函数的执行时机

时间:2021-2-20 作者:admin

今天学习了 JS 的函数, 我来总结一下JS函数的执行时机, 以及举例来理解调用栈

本文是自己总结的, 如有问题请提供帮助, 谢谢!!!

JS 函数是如何调用的?

我们定一个函数并调用这个函数

function fn(){console.log('我被调用了')}fn()console.log('调用fn之后, 再来执行我')

上面这段代码就是简单地对函数fn 进行调用

先打印出 ‘我被调用了’, 然后再打印出 ‘调用fn之后, 再来执行我’

在JS 引擎里, 上面这段代码是怎么知道我先调用了fn 呢?

知道了之后, 又怎么找到 fn 后面代码的呢?

这里就用到了 JS 引擎里的 调用栈

  1. 在执行到 fn() 的时候, JS引擎 记录了所在的位置, 我们假设为

  2. 然后进行了 入栈并压栈 的操作

  3. 这样我们的调用栈里就记录了fn()

  4. 然后进入fn函数中, JS 引擎记录console.log('我被调用了') 的位置, 假设为

  5. 继续入栈并压栈

  6. 然后 JS 引擎记录console.log('调用fn之后, 再来执行我') 的位置, 假设为

  7. 继续入栈并压栈

  8. JS引擎, 发现没东西了, 就开始执行栈里的了

  9. 先进入的先出来

  10. 这就是弹栈, 依次执行, 每弹一个, 栈里就结束一个

  11. 一直到栈里全部结束

  12. 这就是JS 函数的执行时机

下面这张图片, 结合上面的文字更好理解

解释为什么如下代码会打印 6 个 6

下面这段代码, 为什么如下代码会打印 6 个 6?

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

因为先入栈, 然后才会弹
所以每次setTimeout都会先入栈, 弹的时候在执行
可是执行的时候是for结束循环的时候
这时候, i就是6了, 导致每次执行都是
写出让上面代码打印 0、1、2、3、4、5 的方法
for(let i = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}

利用 let会产生块级作用域
每一个栈里面的 setTimeout 的 i是独立的
除了使用 for let 配合,还有什么其他方法可以打印出 0、1、2、3、4、5

setTimeout 第三个参数

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

闭包 + 立即执行函数

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

利用 const 关键字

let i
for(i = 0; i<6; i++){
    const x = i
    setTimeout(()=>{
      console.log(x)
    })
}
总结:
  • JS函数的执行, 需要参考调用栈

  • 调用栈是基于JS引擎的

  • 规律就是先入栈的先出

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。