全局tdz起始点为脚本第一行,只要存在let/const声明,其变量从脚本顶部到声明执行完毕前均处于tdz;typeof访问会抛出referenceerror而非返回"undefined";判断依据是执行点是否在其声明文本位置之前。

全局执行上下文中的暂时性死区(TDZ)和函数或块级作用域里的 TDZ 本质一致,但它的起始点更隐蔽:不是从某个 {} 开始,而是从脚本顶部、全局作用域一进入就生效。
全局 TDZ 的起始位置在哪
只要脚本中出现任意一个 let 或 const 声明,整个全局作用域(即全局执行上下文)对该变量立即建立 TDZ —— 从脚本第一行开始,直到该变量声明语句执行完毕为止。
- 哪怕声明写在文件末尾,它前面所有代码都处于该变量的 TDZ 内
- TDZ 不依赖缩进或大括号,只取决于词法作用域边界(全局作用域本身就是一个词法环境)
- 多个
let/const各自形成独立 TDZ 区间,互不影响
为什么 typeof 在全局 TDZ 中也不安全
在全局作用域里提前使用 typeof myLet 会直接抛出 ReferenceError,而不是返回 "undefined"。这是因为 TDZ 阻断的是“绑定访问”,而 typeof 在遇到未初始化绑定时,不走“安全兜底”逻辑。
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
-
var声明下:typeof undeclaredVar→"undefined"(变量未声明) -
let声明下:typeof declaredButNotYetInitialized→ReferenceError(已绑定、未初始化) - 关键区别:前者是“不存在”,后者是“存在但不可用”
全局 TDZ 常见踩坑场景
这些错误在全局作用域中极易发生,且报错信息容易误导开发者以为变量没声明。
- 在
let x = 1之前调用console.log(x)或x++ - 函数表达式引用尚未声明的
let变量:const fn = () => x;放在let x前 - 默认参数中跨变量引用:
function f(a = b, b = 1) { }—— 全局调用时a默认值触发b的 TDZ - 模块顶层代码中,
import后面紧接对let的访问(虽然import是提升的,但不会解除 TDZ)
如何判断是否落入全局 TDZ
不需要查作用域链,只需记住一个判断原则:只要变量是用 let 或 const 声明的,且当前执行点位于其声明语句文本位置之前,就一定在它的 TDZ 中。
- 浏览器控制台中执行单行代码,也遵循同一规则 —— 它属于全局上下文的一部分
-
var和函数声明(function name() {})不受 TDZ 影响,它们仍会提升并初始化为undefined - ES6 模块的顶层也是全局执行上下文的一种变体,同样适用 TDZ 规则










