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

新手上路,请多包涵

如以下代码:


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

阅读 1.7k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题