暂时性死区(TDZ)是JavaScript运行时强制执行的访问限制,指let、const和class声明的变量从块作用域开始到声明执行前处于“已存在但未初始化”状态,此时任何读取、写入或typeof检查均抛出ReferenceError;其本质是声明提升但不初始化,需确保所有访问严格位于声明之后。

暂时性死区(TDZ)不是语法错误,而是 JavaScript 引擎在运行时强制执行的访问限制:只要进入块作用域,用 let、const 或 class 声明的变量就已存在,但尚未初始化——此时任何读取、写入、甚至 typeof 检查都会直接抛出 ReferenceError。
TDZ 是怎么产生的
本质是“声明提升 + 不初始化”的组合结果:
-
let和const的声明确实会被提升到块级作用域顶部,但引擎只分配内存,不赋予默认值(不像var会初始化为undefined) - 从块开始到声明语句执行前,变量处于“已存在却不可用”状态,这段区域就是 TDZ
-
class同样适用该规则:定义前不能new实例,也不能在类体内引用尚未声明的静态属性
容易忽略的 TDZ 触发场景
有些 TDZ 不在代码线性顺序里,容易误判:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
函数参数默认值:参数有自己的作用域,若默认值表达式引用了后面才声明的同名变量,就会报错。例如:
function fn(x = y) { let y = 1; }—— 调用fn()时y还没声明 -
块内嵌套作用域:比如
if块中用了let x,外部同名变量会被屏蔽,而该if块开头就进入了x的 TDZ -
typeof不再安全:过去常用typeof xxx === 'undefined'判断变量是否存在,现在对let/const变量这么做会直接报错,不能再当“防御性检查”用
如何避免 TDZ 报错
核心原则只有一条:所有使用必须严格出现在声明之后。落地建议如下:
立即学习“Java免费学习笔记(深入)”;
- 把
let和const声明尽量放在块作用域最开头(如函数体第一行、if块起始处) - 函数参数默认值中,避免引用尚未声明的局部变量;需要依赖逻辑时,改到函数体内处理
- 不要用
typeof检测let/const变量;可用try/catch包裹访问,或提前用明确的初始化逻辑兜底(比如设为null或空对象)
为什么 var 没有 TDZ
var 存在变量提升且自动初始化为 undefined,所以声明前访问得到的是 undefined,不会报错。而 let/const 的设计初衷,正是为了暴露“提前使用变量”这类潜在错误,让问题在开发阶段就被发现,而不是隐性地返回 undefined 导致逻辑异常。

















