内部函数查找作用域链前,能否识别变量处于暂时性死区?
function b() { function a() { console.log(x); } a(); const x = 10; } const x = 20; b()
若我对词法作用域与执行上下文的理解无误,调用函数a()时,它应能引用函数b的词法环境。在a()执行过程中,b()内部的const变量x处于暂时性死区(TDZ),直到a执行完成。但为何a()未识别到该x无法访问(因处于TDZ),进而去全局词法环境查找const x = 20?
上述案例中,a()抛出了引用错误。
问题解析
这核心是词法作用域的绑定时机和暂时性死区(TDZ)的本质在起作用:
词法作用域是在代码编译阶段就确定的,不是运行时。函数a定义在函数b内部,所以a的作用域链里,b的作用域排在全局作用域前面。当a里引用
x时,编译阶段就已经确定了这个x是指向b作用域里的x,不会等到运行时再去“找”。暂时性死区不是说这个变量不存在,而是变量已经被作用域绑定了,但还没完成初始化。b作用域里的
const x在编译阶段就已经被注册到b的词法环境中了,所以a引用x时,会直接定位到这个已经绑定但未初始化的变量,而不会跳过它去全局作用域找同名变量。当在TDZ内访问这个变量时,JS引擎会直接抛出
ReferenceError,这是const/let的特性——不允许在声明前访问已绑定但未初始化的变量,和var的变量提升(会初始化undefined)完全不同。
简单说:不是a“没识别到x无法访问”,而是它从一开始就锁定了要访问b作用域里的x,而这个x还在TDZ里,直接触发错误,根本不会去全局作用域查找。
内容的提问来源于stack exchange,提问作者james
相关产品推荐
相关产品推荐

