You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何变量遮蔽时无法引用原变量?Block A为何触发ReferenceError?

让我来把这两个问题拆解清楚,帮你理解JavaScript变量遮蔽背后的逻辑~

为什么在遮蔽变量时无法引用该变量?

这本质上是**暂时性死区(Temporal Dead Zone,TDZ)**在起作用。当你在一个块级作用域里用let或const声明一个和外层同名的变量时,这个变量的绑定会在作用域创建时就被“提升”了,但它并不会被初始化——从作用域开始到变量声明语句执行前的这段时间,就是这个变量的暂时性死区。

在TDZ内,你根本无法访问这个变量,哪怕外层有同名的变量也不行。因为JavaScript引擎会优先在当前作用域查找变量绑定,一旦当前作用域存在这个变量的声明(哪怕还没初始化),就不会去外层作用域寻找了。这种设计是为了避免变量未初始化就被使用的潜在bug。

为什么代码块A会触发ReferenceError?

先把你的代码再贴出来方便分析:

const something = 'something';
console.log ();
try {
  // Block A
  { const something = something; }
} catch (e) {
  console.log(e);
}
console.log ();
// Block B
{ const something = 'somethingElse'; }

代码块A的问题分析

在Block A的{ const something = something; }这句话里:

  1. 当进入这个块作用域时,const something的变量绑定就已经存在了(进入TDZ);
  2. 等号右边的something,JavaScript引擎会先在当前块作用域查找,发现已经有这个变量的绑定了,所以不会去外层找那个已经初始化的something;
  3. 但此时当前作用域的something还处于暂时性死区,还没有被初始化(要等赋值完成才会初始化),所以尝试访问它就会直接抛出ReferenceError。

代码块B为什么没问题?

Block B里的{ const something = 'somethingElse'; },等号右边是一个字符串字面量,不是对变量的引用。所以JavaScript引擎不需要去查找任何变量绑定,直接把字面量赋值给新声明的something,变量完成初始化后就脱离了TDZ,自然不会报错。

你提到的“这种机制可防止用变量的某个属性来遮蔽该变量本身”,其实就是这个逻辑的延伸——比如如果允许这种写法,有人可能会写出const obj = obj.someProp这样的代码,结果obj还没初始化就被用来访问属性,这显然是错误的,TDZ机制就提前把这种bug拦下来了。


内容的提问来源于stack exchange,提问作者Stephen Carboni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:10:04