脚本顶层作用域中LexicalEnvironment与VariableEnvironment指向是否一致?
问题解答
疑问1:初始状态LE和VE是否指向同一个Environment Record?
是。执行上下文初始化阶段,LexicalEnvironment(以下简称LE)和VariableEnvironment(以下简称VE)完全指向同一个环境记录(Environment Record,以下简称ER),二者只是同一ER的不同引用,没有任何差异。
疑问2:顶层存在let/const声明时是否会创建新ER并让LE指向它?
是,且你给出的猜想2是正确逻辑,猜想1存在明显漏洞:
- 猜想1的问题:如果LE的
[[outerEnv]]设为null,作用域链查找时完全无法访问到VE中绑定的var声明变量,和实际运行中全局var/函数声明可正常访问的表现矛盾,因此不可能成立。 - 猜想2的逻辑完全符合ECMA262 2022规范要求:
- VE在全局执行上下文的整个生命周期中不会修改指向,始终绑定和全局对象关联的ER,所有
var、顶层函数声明都会绑定到这个ER上,对应示例中的变量b。 - 处理顶层
let/const/class这类块级声明时,会创建新的声明式ER,该ER的[[outerEnv]]指向VE对应的原ER,之后LE会改为指向这个新ER,所有块级声明的变量都会绑定到这个新ER上,对应示例中的变量a。 - 变量查找时会顺着
[[outerEnv]]构成的作用域链逐层向上匹配:访问a时直接在LE指向的新ER中找到,访问b时顺着[[outerEnv]]找到VE对应的ER就能拿到绑定,完全符合JS实际运行表现。
- VE在全局执行上下文的整个生命周期中不会修改指向,始终绑定和全局对象关联的ER,所有
补充说明:部分规范解读会把顶层声明式ER和绑定全局对象的ER合并表述为「复合全局环境记录」,本质和猜想2的分层逻辑完全一致,只是表述形式不同。
内容的提问来源于stack exchange,提问作者用户17435438
相关产品推荐
相关产品推荐

