为什么let变量初始化会出现ReferenceError引用错误?
为什么
let f = f;会抛出引用错误? 先看这段代码:
let f = f;
执行时会抛出如下错误:
ReferenceError: can't access lexical declaration 'f' before initialization
你已经知道变量声明分为三个步骤:
- Declaration(声明)
- Initialization(初始化)
- Assignment(赋值)
我们来拆解这段代码实际的执行逻辑,解答你的困惑:
实际执行步骤
- 声明阶段:JS引擎先在当前作用域中注册变量
f,此时f进入暂时性死区(TDZ)——变量已存在于作用域,但无法被访问或读取。 - 计算右侧表达式:接下来执行赋值操作,首先需要计算赋值符号右侧的
f。但此时f还处于TDZ中,因为let变量的初始化操作要等到右侧表达式计算完成后才会执行。 - 触发错误终止执行:由于尝试读取TDZ中的变量,直接抛出
ReferenceError,后续的初始化和赋值步骤根本不会被执行。
纠正你的分析误区
你写的模拟代码存在逻辑偏差:
let f = f; Reach declaration statement let f = undefined; //initialization let f = f; //Why did a reference error occur?
错误在于认为初始化会先于右侧表达式的计算执行。实际上,let变量的初始化不是提前完成的,而是和声明语句的执行流程绑定:只有当右侧表达式计算完成后,引擎才会把变量从TDZ中移出,完成初始化(无赋值时默认设为undefined)。
举个对比例子,这样写就不会报错:
let f; // 执行到这里时,f完成初始化,从TDZ中移出,值为undefined f = f; // 此时读取f是合法的,赋值后f还是undefined
内容的提问来源于stack exchange,提问作者Soso
相关产品推荐
相关产品推荐

