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

will 0
11月10日提问
0 个回答

撰写答案

推广链接