暂时性死区(tdz)指let、const和class声明的变量从块作用域开始到声明执行前不可访问,访问即抛referenceerror;var因提升并初始化为undefined而无tdz。

暂时性死区(Temporal Dead Zone,简称 TDZ)指的是在块级作用域中,使用 let、const 或 class 声明的变量,从作用域开始到声明语句执行完成前,这段区域里变量不可访问——哪怕只是读取或用 typeof 检查,都会直接抛出 ReferenceError。
TDZ 出现在哪些地方
它不是语法错误,而是 JavaScript 引擎强制执行的运行时限制,主要影响以下三类声明:
-
let 变量:声明前访问会报错,即使只声明没赋值(
let x;),声明前仍处于 TDZ - const 变量:必须声明即初始化,声明前访问必然报错;声明但未赋值的写法本身就不合法
-
class 声明:和
let类似,定义前不能用new实例化,也不能在 class 内部引用自身(如静态方法中提前调用尚未定义的静态属性)
为什么 var 没有 TDZ
var 存在变量提升(hoisting),声明会被提升到作用域顶部并初始化为 undefined,所以即使在声明前访问,结果是 undefined 而非报错。而 let 和 const 虽然也“被提升”,但引擎只是为其分配内存空间,并不初始化——这个“已存在但未初始化”的中间状态,就是 TDZ 的本质。
容易踩坑的隐蔽场景
有些 TDZ 不在直观的代码顺序里,需特别注意:
-
函数参数默认值:参数形成独立作用域,若默认值表达式中引用了后续才声明的同名变量,会触发 TDZ。例如:
function fn(x = y) { let y = 1; }—— 调用fn()时,y尚未声明,x = y报错 -
块级作用域嵌套:比如
if或for块内有let,外部同名变量会被屏蔽,块开头就进入该变量的 TDZ -
typeof 不再安全:过去用
typeof xxx === 'undefined'判断变量是否存在很常见,但现在对let/const变量这么做会直接报错,不能再依赖它做防御性检查
如何避免 TDZ 报错
核心原则只有一条:确保所有 let、const、class 的使用都严格出现在其声明之后。具体可这样做:
- 把变量声明尽量放在块作用域的开头,尤其是函数体、
if块、循环体内 - 避免在函数参数默认值中引用尚未声明的局部变量;如需依赖,改用函数体内部逻辑处理
- 不要依赖
typeof检测let/const变量是否存在;改用try/catch或明确的初始化逻辑 - 使用 ESLint 插件(如
no-use-before-define)在开发阶段捕获潜在的 TDZ 访问
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











