JS函数调用时LexicalEnvironment与VariableEnvironment结构疑问
结论
示例1是正确的,let localVar会存储在LE和VE初始共同指向的FunctionEnvironmentRecord中,不需要新建环境记录(ER)。
原因说明
- 你提到的
PrepareForOrdinaryCall执行逻辑完全符合ECMA262规范,函数执行上下文初始化阶段,LexicalEnvironment(LE,词法环境)和VariableEnvironment(VE,变量环境)确实指向同一个函数环境记录实例。 - 规范中只有当进入独立块级作用域(也就是
{}包裹的代码块,比如if/for的执行体、单独写的{}块语句等)时,才会创建新的块级环境记录,临时将执行上下文的LE切换为这个新ER,块内的let/const声明才会绑定到这个新ER上,块执行结束后LE会切回原有的环境记录。 - 你给出的示例中
let localVar直接声明在函数顶层,没有嵌套在额外的块级作用域中,不会触发新ER的创建。var声明的myVar和let声明的localVar都会绑定到同一个函数环境记录中,二者的区别只是环境记录内部存储的绑定类型不同,不需要拆分到两个ER里。
补充:示例2的触发场景
只有当let声明在嵌套块内时,才会出现新建ER的逻辑,示例如下:
function test(){ var myVar = 10; // 进入块级作用域,触发新ER创建 { let localVar = 5; // 存储在新建的块级ER中,此时LE指向这个新ER,VE仍指向原函数ER } // 块执行结束,LE切回原函数ER } test();
内容的提问来源于stack exchange,提问作者AngryJohn
相关产品推荐
相关产品推荐

