只有含 let/const 声明的语法块(如 if、for、while 等代码体)中的大括号才构成块级作用域,单纯 {} 不形成作用域。

大括号 {} 本身不自动构成块级作用域,关键看里面有没有用 let 或 const 声明变量。只有当大括号内出现 let/const 声明时,这组花括号才真正成为有独立生命周期的块级作用域。
哪些大括号能形成块级作用域
不是所有 {} 都有效,必须满足“声明 + 语法块”两个条件:
-
if / else / switch 的代码体:如
if (true) { let x = 1; }→x只在该{}内可访问 -
for / while / do...while 循环体:如
for (let i = 0; i → 每次迭代都新建一个 <code>i绑定 -
裸代码块(labelled 或无标签):如
{ const a = 'test'; console.log(a); }→a离开这个{}就报错 -
函数体内任意位置的
{}:哪怕只是加了一对空花括号并声明了let b,也立即隔离出新作用域
哪些大括号“看起来像”但不算
仅靠大括号本身无法触发块级作用域机制,以下情况仍沿用函数或全局作用域:
-
只用
var声明:如if (true) { var y = 1; }→y会被提升到所在函数或全局作用域 -
没声明任何变量:如
{ console.log('hello'); }→ 这个{}是语法块,但不产生新词法环境 -
对象字面量或函数参数中的
{}:如const {a} = obj或function f({x}){}→ 这是解构语法,不是作用域边界
怎么验证是不是真正的块级作用域
最直接的方式是尝试在大括号外读取其中声明的变量:
立即学习“Java免费学习笔记(深入)”;
- 用
let/const声明 → 外部访问抛ReferenceError(不是undefined) - 用
var声明 → 外部可能正常读到值,或为undefined(因变量提升) - 未声明直接赋值(如
{ z = 123; })→z成为全局变量,可在外部访问
一个易忽略的关键点:TDZ(暂时性死区)
只要用了 let/const,大括号一打开就进入 TDZ:
- 在声明语句执行前,任何对该变量的读写都会报错
- 例如:
{ console.log(x); let x = 1; }→ 直接报错,不输出undefined - 这说明:作用域边界从左大括号开始,不是从声明行开始


















