javascript中闭包嵌套setTimeout时调用栈的情况?

发布于 2022-09-11 23:25:36 字数 1350 浏览 22 评论 0

如以下代码:


for (var i = 0; i < 5; i++) {

    setTimeout(function timer() {

        console.log(i);

    }, 1000 * i);

}

个人理解如下:

  1. 主线程运行代码,调用栈中加入全局匿名调用函数
  2. 执行for循环,遇setTimeout,将setTimeout加入event table注册,当for循环遍历结束,调用栈中只有最初的全局匿名函数。
  3. 主线程同步代码执行结束,在调用task queue时,调用栈加入timer函数,一个setTimeout回调执行结束,取出timer函数,event loop循环直到所有运行结束。

又如以下代码:


for (var i = 0; i < 5; i++) {

    (function autorun(j) {

        setTimeout(function timer() {

            console.log(j)

        }, j * 1000)

    })(i)

}

理解如下:

  1. 主线程运行代码,调用栈中加入全局匿名调用函数
  2. 执行for循环
  3. 遇自执行函数autorun,将autorun加入调用栈。
  4. setTimeout加入定时器线程。
  5. 继续执行将autorun取出调用栈。
  6. 继续下一循环,如同3~5执行,只有参数变化。
  7. for循环执行结束,取出task queue中的setTimeout回调函数并执行,此时调用栈有如下图的调用函数。

问:此时调用栈里的autorun是从哪里出来的,在之前已取出调用栈了?它是否与for循环时的autorun相同?这里的setTimeout上下文在调用栈里是如何变化和记录的?

image.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文