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

为何两段JavaScript代码运行结果不同?一段报ReferenceError一段正常

JavaScript词法环境与暂时性死区问题解析

问题根源:暂时性死区(TDZ)

你碰到的这个报错,核心原因是let声明的变量存在暂时性死区,这和JavaScript词法环境的创建逻辑直接相关,和你预期的“先找外层变量再报错”完全不同。

两段代码的执行差异

报错代码的运行过程

let x = 1;

function func() {
  console.log(x); 
  let x = 2;
}

func();

当调用func时,函数的执行上下文会先创建自己的词法环境:

  1. 第一步就会扫描整个函数作用域,把所有let/const声明的变量(这里就是x)注册到当前词法环境里,但不会给它们赋值。
  2. 从这时候开始,到let x = 2执行完成前,这个x就处于暂时性死区——它已经被声明了,但完全不可访问,任何对它的引用都会直接抛出ReferenceError。
  3. 所以console.log(x)执行时,JavaScript会优先找当前作用域的x,但这个x还在TDZ里,根本不会去外层全局作用域找那个x=1,直接报错。

正常代码的运行过程

let x = 1;

function func() {
  console.log(x);
}

func(); // logs out 1

这段代码里,func内部没有声明自己的x,所以执行console.log(x)时,JavaScript会沿着作用域链往上找,找到全局作用域里已经初始化完成的x,自然就输出1了。

关键知识点总结

  • var声明的变量会被提升并默认赋值undefined,但let/const只提升声明,不做初始化,直接进入暂时性死区。
  • 在暂时性死区内引用变量,不会去外层作用域查找,直接报错——这是let/const和var最核心的区别之一。
  • 词法环境的创建分两步:先注册变量,再执行赋值初始化,暂时性死区就是这两步之间的“真空期”。

内容的提问来源于stack exchange,提问作者The Curious Cat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:06:19