let和const声明的变量由词法环境管理,遵循块级作用域:仅在声明所在代码块内可访问,跨块引用报referenceerror,不同块同名变量互不影响,for循环每次迭代创建独立绑定。

函数执行上下文中,let 和 const 声明的变量不绑定到变量环境(VE),而是由词法环境(LE)管理,并严格遵循块级作用域规则。它们的行为与 var 有本质区别,核心在于作用域边界、初始化时机和访问限制。
块级作用域生效范围明确
在函数内部的任意代码块(如 if、for、switch、{...})中用 let/const 声明的变量,只在该块内可访问:
- 超出该块(哪怕仍在同一函数内),引用会报
ReferenceError - 不同块中同名 let/const 互不影响,不会覆盖或提升到外层函数作用域
- for 循环中每次迭代都会创建独立的绑定(例如
for (let i = 0; i 中每个 i 是隔离的)
不参与变量提升,存在暂时性死区(TDZ)
let/const 在其所在块的顶部到声明语句之间处于“暂时性死区”:
- 在此区域内访问该变量,直接抛出
ReferenceError,而非返回undefined - TDZ 不是“未初始化”,而是语法禁止访问——引擎在解析阶段就标记了该绑定不可用
- 即使块内有嵌套函数,在 TDZ 内调用它并试图访问该变量,同样报错
绑定归属词法环境,支撑闭包与作用域链
let/const 绑定被记录在当前块对应的词法环境记录(Lexical Environment Record)中:
- 该 LE 通过 outer 引用链接到外层(函数或全局)词法环境,构成作用域链
- 当内部函数形成闭包时,它捕获的是这个块级 LE 的引用,因此能持续访问块内 let/const 变量
- 块执行结束时,若无闭包引用,该 LE 可被垃圾回收;若有,则保留对应绑定
与 var 在函数上下文中的关键对比
同一函数内混用时,行为差异明显:
-
var x声明会被提升至函数顶部,初始化为undefined,存在于变量环境(VE) -
let y声明只在其块内有效,不提升,不存在于 VE,只存于对应块的 LE - 两者同名时,let/const 会遮蔽(shadow)外层 var,但不会导致重复声明错误(因作用域不同)
- 块内用 let 声明同名变量,不会影响块外同名 var 的值或生命周期











