当JS代码开始运行时,全局执行上下文被创建并位于执行堆栈的底部,以“容纳”全局变量对象和'this'
。
如果在运行整个JS代码并且没有全局执行上下文后执行堆栈变空, 我们如何仍然能够访问全局变量 (例如,我正在运行带有JS代码的html文件,完成后,我仍然能够通过Chrome控制台查看全局变量的值...)或 如何{{1}仍然指向全局对象 (如果没有任何执行上下文,则不应该有this
!)?
我可能给自己的唯一解释是全局执行上下文永远不会离开执行堆栈;它一直存在,直到我决定关闭浏览器窗口。 我是对还是没有?
此外,在异步回调的情况下,当一个事件离开事件队列并进入JS引擎运行时,执行堆栈中究竟发生了什么?回调的执行上下文是否位于此堆栈的底部,或者全局执行上下文仍然存在?
有一个类似的主题Is the initial global execution context ever popped off the call stack in JavaScript?;但是,它没有回答我的问题。
谢谢
答案 0 :(得分:11)
运行整个代码时执行堆栈变空。
我们如何才能访问全局变量?
即使没有执行代码the global lexical environment,全局对象仍然存在。当您将某些代码提供给chrome控制台时,正在评估代码,新的全局execution context为being created and initialized,其词法和变量环境设置为全局环境,this
绑定到全局环境宾语。然后你的代码在这个上下文中执行,执行堆栈再次变空。
this
如何仍然指向全局对象?
每次使用全局代码初始化新的全局执行上下文时,this
都会绑定到全局对象。
在异步回调的情况下,当一个事件离开事件队列并进入JS引擎运行时,执行堆栈中到底发生了什么?
同样,创建一个新的全局执行上下文并将其推送到空执行堆栈。 MDN ECMAScript spec中的描述与MDN. Concurrency model and event loop中的术语略有不同:
当堆栈为空时,会从队列中取出一条消息并进行处理。处理包括调用相关函数(从而创建初始堆栈帧)。当堆栈再次变空时,消息处理结束。 (ECMAScript 6.0 spec)
这里"堆叠框架"意味着"执行环境"和"初始堆栈帧"对应于"全局执行上下文"。
回调的执行上下文是否位于此堆栈的底部,还是全局执行上下文仍然存在?
他们都不是。堆栈是空的。并且只有当它为空时,最旧的回调才从回调/事件队列中获取:
当没有正在运行的执行上下文且执行上下文堆栈为空时,ECMAScript实现从作业队列中删除第一个PendingJob,并使用其中包含的信息创建执行上下文并开始执行关联的Job抽象操作。 {{3}}