全局执行上下文是否可以从执行堆栈中弹出?

时间:2015-11-23 10:46:33

标签: javascript event-handling

当JS代码开始运行时,全局执行上下文被创建并位于执行堆栈的底部,以“容纳”全局变量对象和'this'。 如果在运行整个JS代码并且没有全局执行上下文后执行堆栈变空, 我们如何仍然能够访问全局变量 (例如,我正在运行带有JS代码的html文件,完成后,我仍然能够通过Chrome控制台查看全局变量的值...)或 如何{{1}仍然指向全局对象 (如果没有任何执行上下文,则不应该有this!)?

我可能给自己的唯一解释是全局执行上下文永远不会离开执行堆栈;它一直存在,直到我决定关闭浏览器窗口我是对还是没有?

此外,在异步回调的情况下,当一个事件离开事件队列并进入JS引擎运行时,执行堆栈中究竟发生了什么?回调的执行上下文是否位于此堆栈的底部,或者全局执行上下文仍然存在?

有一个类似的主题Is the initial global execution context ever popped off the call stack in JavaScript?;但是,它没有回答我的问题。

谢谢

1 个答案:

答案 0 :(得分:11)

运行整个代码时执行堆栈变空。

  

我们如何才能访问全局变量?

即使没有执行代码the global lexical environment,全局对象仍然存在。当您将某些代码提供给chrome控制台时,正在评估代码,新的全局execution contextbeing created and initialized,其词法和变量环境设置为全局环境,this绑定到全局环境宾语。然后你的代码在这个上下文中执行,执行堆栈再次变空。

  

this如何仍然指向全局对象?

每次使用全局代码初始化新的全局执行上下文时,this都会绑定到全局对象。

  

在异步回调的情况下,当一个事件离开事件队列并进入JS引擎运行时,执行堆栈中到底发生了什么?

同样,创建一个新的全局执行上下文并将其推送到空执行堆栈。 MDN ECMAScript spec中的描述与MDN. Concurrency model and event loop中的术语略有不同:

  

当堆栈为空时,会从队列中取出一条消息并进行处理。处理包括调用相关函数(从而创建初始堆栈帧)。当堆栈再次变空时,消息处理结束。 (ECMAScript 6.0 spec

这里"堆叠框架"意味着"执行环境"和"初始堆栈帧"对应于"全局执行上下文"。

  

回调的执行上下文是否位于此堆栈的底部,还是全局执行上下文仍然存在?

他们都不是。堆栈是空的。并且只有当它为空时,最旧的回调才从回调/事件队列中获取:

  

当没有正在运行的执行上下文且执行上下文堆栈为空时,ECMAScript实现从作业队列中删除第一个PendingJob,并使用其中包含的信息创建执行上下文并开始执行关联的Job抽象操作。 {{3}}