暂时性死区(tdz)是javascript中let/const变量在作用域内“已绑定未初始化”的不可访问区间,始于作用域入口、止于声明执行完毕,访问即抛referenceerror。

暂时性死区(Temporal Dead Zone,TDZ)不是作用域本身,而是 JavaScript 引擎在作用域内对 let 和 const 变量施加的一段“不可访问区间”。它从作用域开始处起算,一直持续到变量声明语句执行完成——在这期间,哪怕变量已“存在”,也不能读、不能写、甚至不能用 typeof 检测,否则直接抛出 ReferenceError。
TDZ 的起点和范围由作用域边界决定
TDZ 始于块级作用域(如函数体、{} 代码块、模块顶层)的入口,止于对应 let 或 const 声明语句执行完毕。不是“看到声明才开始”,而是“进入该作用域就启动”。
- 全局作用域中,TDZ 从脚本加载/模块解析开始,直到
let x = 1这行执行完 - 函数内部,TDZ 从函数被调用、执行流进入函数体第一行起,覆盖所有未声明前的语句
-
if (true) { console.log(a); let a = 2; }中,a的 TDZ 就在{到let a = 2;之间
TDZ 是绑定(binding)与初始化分离的直接结果
引擎在作用域创建阶段就为 let/const 创建绑定(即登记变量名),但不赋初始值;只有执行到声明语句时,才完成初始化。中间这段“已绑定、未初始化”的状态,就是 TDZ。
-
var是声明+初始化(默认为undefined)一步到位,所以没有 TDZ -
let a单独写(无赋值)也会触发 TDZ:只要声明出现,TDZ 就存在,直到该语句执行完 -
const必须带初始化,因此它的 TDZ 总是短于let(声明即初始化),但规则完全一致
TDZ 不是语法错误,而是运行时访问限制
代码能正常解析,也能进入执行阶段;报错只发生在“试图访问一个处于 TDZ 中的绑定”这一瞬间。这说明 TDZ 是语言规范强制的运行时行为,不是词法或语法层面的禁止。
-
console.log(typeof a)在 TDZ 内同样报错,不同于var下返回"undefined" - 函数参数作用域也适用 TDZ:
function f(x = y) { let y = 1; }中,y在参数默认值求值时仍处于 TDZ,会报错 - 类字段、
import绑定也遵循 TDZ 规则,体现其作为 ES6+ 统一绑定模型的一部分
控制台里看不到标准 TDZ?那是环境限制,不是规范失效
浏览器控制台是 REPL 环境,逐行解析执行,不会预扫描整段代码。所以把 console.log(a); let a = 1; 分两行粘贴,第一行会报 a is not defined(因为尚未声明),而非标准 TDZ 错误 Cannot access 'a' before initialization。
- 要真实验证 TDZ,必须将代码封装进函数、IIFE 或模块中,确保引擎进行完整的作用域扫描
- Node.js 脚本文件、ES 模块、打包后的 bundle 都严格遵循 TDZ 规范
- 别让控制台行为误导你对语言本质的理解——TDZ 是规范要求,不是调试器特性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











