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

关于JavaScript作用域与Hoisting(变量提升)的新手疑问求解

问题核心原因:const/let 存在暂时性死区(Temporal Dead Zone,简称TDZ)

你对作用域和变量提升的认知存在部分偏差,核心是没有区分不同声明类型的提升行为差异:

不同声明类型的提升规则

  • 函数声明的提升:会同时将声明、函数体定义都提升到当前作用域顶部,因此无论在声明前还是声明后调用都可以正常执行,这也是你前两个例子中函数调用不会报错的原因。
  • var 声明的提升:仅将声明提升到作用域顶部,初始化值为undefined,提前访问只会拿到undefined,不会抛出引用错误。
  • const/let 声明的提升:确实会将声明提升到当前作用域顶部,但不会提前完成初始化,从作用域顶部到变量正式完成赋值的这段区间,就是该变量的暂时性死区,在死区内访问该变量会直接抛出ReferenceError。

针对第三个报错案例的执行逻辑拆解

你的第三段代码:

function test() {
  console.log(`${firstName}`)
};
test();
const firstName = 'a';

实际执行顺序如下:

  1. 全局作用域预解析阶段:首先提升函数声明test,同时提升const firstName的声明(但不做初始化,firstName进入暂时性死区)
  2. 逐行执行代码阶段:
    • 先调用test(),函数内部尝试访问firstName,此时firstName还处于全局作用域的暂时性死区内,未完成初始化,因此直接抛出引用错误
    • 后续才会执行到const firstName = 'a',这一步才会结束暂时性死区,给变量完成赋值

补充验证小技巧

你可以观察报错信息:第三段代码的报错是Cannot access 'firstName' before initialization,而非firstName is not defined,这也说明JS已经识别到全局作用域下存在firstName的声明,只是还没初始化,足以证明const是存在提升行为的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 05:09:03