块语句

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

块语句用于将零个或多个语句分组。块由一对大括号(“花括号”)分隔,并包含一个零个或多个语句和声明的列表。

试一试

var x = 1;
let y = 1;

if (true) {
  var x = 2;
  let y = 2;
}

console.log(x);
// Expected output: 2

console.log(y);
// Expected output: 1

语法

js
{
  StatementList
}
语句列表

在块语句中分组的语句和声明。

描述

块语句在其他语言中通常被称为复合语句。它允许你在 JavaScript 期望只出现一个语句的地方使用多个语句。将语句组合成块是 JavaScript 中的常见做法,尤其是在与if...elsefor等控制流语句结合使用时。相反的行为可以通过空语句实现,在这种情况下,你没有提供任何语句,尽管需要一个。

此外,与letconstclass等块级声明结合使用时,块可以防止临时变量污染全局命名空间,就像IIFE一样。

在非严格模式下使用 var 或函数声明的块作用域规则

在非严格模式下使用 var 声明的变量或由函数声明创建的变量具有块作用域。在块中引入的变量作用域限定在包含函数或脚本中,并且设置它们的效果会持续到块之外。例如

js
var x = 1;
{
  var x = 2;
}
console.log(x); // 2

这会打印 2,因为块中的 var x 语句与块之前的 var x 语句在同一作用域中。

在非严格代码中,块内的函数声明行为异常。请勿使用它们。

在严格模式下使用 let、const、class 或函数声明的块作用域规则

相反,使用letconstclass声明的标识符确实具有块作用域

js
let x = 1;
{
  let x = 2;
}
console.log(x); // 1

x = 2 的作用域仅限于定义它的块。

const 也是如此

js
const c = 1;
{
  const c = 2;
}
console.log(c); // 1; does not throw SyntaxError

请注意,块作用域的 const c = 2 不会抛出 SyntaxError: Identifier 'c' has already been declared 错误,因为它可以在块内唯一声明。

严格模式下,块内的函数声明作用域限定在该块中,并被提升到块的顶部。

js
"use strict";

{
  foo(); // Logs "foo"
  function foo() {
    console.log("foo");
  }
}

foo(); // ReferenceError: foo is not defined

示例

将块语句用作 for 循环的主体

for 循环接受单个语句作为其主体。

js
for (let i = 0; i < 10; i++) console.log(i);

如果你想在循环体中使用多个语句,可以将它们分组到一个块语句中

js
for (let i = 0; i < 10; i++) {
  console.log(i);
  console.log(i ** 2);
}

使用块语句封装数据

letconst 声明的作用域限定在包含块中。这允许你将数据隐藏在全局作用域之外,而无需将其包装在函数中。

js
let sector;
{
  // These variables are scoped to this block and are not
  // accessible after the block
  const angle = Math.PI / 3;
  const radius = 10;
  sector = {
    radius,
    angle,
    area: (angle / 2) * radius ** 2,
    perimeter: 2 * radius + angle * radius,
  };
}
console.log(sector);
// {
//   radius: 10,
//   angle: 1.0471975511965976,
//   area: 52.35987755982988,
//   perimeter: 30.471975511965976
// }
console.log(typeof radius); // "undefined"

块中的 using 声明

你可以在块中声明带usingawait using的变量,这会导致存储在变量中的对象在控制退出块时被处置。有关更多信息,请参阅资源管理

js
{
  using reader1 = stream1.getReader();
  using reader2 = stream2.getReader();

  // do something with reader1 and reader2

  // Before we exit the block, reader1 and reader2 are automatically released
}

规范

规范
ECMAScript® 2026 语言规范
# sec-block

浏览器兼容性

另见