JS运行过程中,全局执行上下文(global EC)一直在执行上下文栈(ECS)中吗。

最常见的说法是:页面关闭前全局执行上下文会一直在执行上下文栈的最底端,直到页面关闭。

但是,在事件循环中,又有这样的说法:js执行上下文栈为空的时候会检查任务队列……

如果全局执行上下文一直在ECS中,ECS又怎会为空。又或者说,这两个执行上下文栈不是同一个?

阅读 976
评论
    4 个回答
    • 537

    自问自答了:
    执行上下文栈只有一个;
    全局上下文并不会一直在执行上下文栈中。

    也就是说,我们经常听到的全局执行上下文会一直在栈底直到浏览器关闭是错误的理解

    然后我来解释一下:
    1,全局上下文会出栈,并不是一直在栈底。
    全部代码运行结束,ECS就为空,也就是说,全局执行上下文会出栈,但是全局词法环境(global lexical environment)还存在。
    2,执行全局代码的时候会再次创建全局上下文。
    当你执行全局的代码的时候(例如,从控制台执行代码),浏览器就会将全局词法环境用来创建全局上下文(当然,全局上下文中不只有这个)。然后,代码就会在这个全局上下文中执行。
    3,事件循环中执行队列中的事件时会再次创建上下文。
    当ECS为空时,浏览器会从任务队列中删除一条任务,并且用这条任务相关的信息创建执行上下文,也就是全局上下文。
    关于这点可以直接参考MDN

    At some point during the event loop, the runtime starts handling the messages on the queue, starting with the oldest one. To do so, the message is removed from the queue and its corresponding function is called with the message as an input parameter. As always, calling a function creates a new stack frame for that function's use.

    以及ES2015规范

    A request for the future execution of a Job is made by enqueueing, on a Job Queue, a PendingJob record that includes a Job abstract operation name and any necessary argument values. When there is no running execution context and the execution context stack is empty, the ECMAScript implementation removes the first PendingJob from a Job Queue and uses the information contained in it to create an execution context and starts execution of the associated Job abstract operation.

    这个答案主要参考自:StackOverflow上的这个回答

    最后,强烈建议JavaScript学的好并且英语好的去看看上面的规范,然后帮忙看一下我的理解有没有问题,毕竟我的理解能力有限。

      相似问题
      推荐文章