标签语句

Baseline 已广泛支持

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

带标签的语句是任何以标识符为前缀的语句。你可以使用嵌套在带标签语句中的breakcontinue语句跳转到此标签。

试一试

let i, j;

loop1: for (i = 0; i < 3; i++) {
  loop2: for (j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      break loop1;
    }
    console.log(`i = ${i}, j = ${j}`);
  }
}

// Expected output:
// "i = 0, j = 0"
// "i = 0, j = 1"
// "i = 0, j = 2"
// "i = 1, j = 0"

语法

js
label:
  statement
label

任何非保留字的 JavaScript 标识符

statement

一个 JavaScript 语句。break 可用于任何带标签的语句,而 continue 可用于带标签的循环语句。

描述

你可以使用标签来标识一个语句,然后使用 breakcontinue 语句引用它。请注意,JavaScript 没有 goto 语句;你只能将标签与 breakcontinue 一起使用。

任何引用 labelbreakcontinue 都必须包含在由 label 标记的 statement 中。可以将 label 视为一个仅在 statement 作用域内可用的变量。

如果在执行 statement 时遇到 break label; 语句,则 statement 的执行终止,并在带标签语句之后的语句处继续执行。

仅当 statement循环语句之一时,才能使用 continue label;。如果在执行 statement 时遇到 continue label; 语句,则 statement 的执行将在循环的下一次迭代中继续。不带标签的 continue; 只能继续最内层循环,而 continue label; 允许继续任何给定循环,即使该语句嵌套在其他循环中。

一个语句可以有多个标签。在这种情况下,所有标签在功能上都是等效的。

示例

在 for 循环中使用带标签的 continue

js
// The first for statement is labeled "loop1"
loop1: for (let i = 0; i < 3; i++) {
  // The second for statement is labeled "loop2"
  loop2: for (let j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      continue loop1;
    }
    console.log(`i = ${i}, j = ${j}`);
  }
}

// Logs:
// i = 0, j = 0
// i = 0, j = 1
// i = 0, j = 2
// i = 1, j = 0
// i = 2, j = 0
// i = 2, j = 1
// i = 2, j = 2

请注意它是如何跳过“i = 1, j = 1”和“i = 1, j = 2”的。

在 for 循环中使用带标签的 break

js
let i, j;

// The first for statement is labeled "loop1"
loop1: for (i = 0; i < 3; i++) {
  // The second for statement is labeled "loop2"
  loop2: for (j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      break loop1;
    }
    console.log(`i = ${i}, j = ${j}`);
  }
}

// Logs:
// i = 0, j = 0
// i = 0, j = 1
// i = 0, j = 2
// i = 1, j = 0

请注意与上一个 continue 示例的区别:当遇到 break loop1 时,外部循环的执行终止,因此除了“i = 1, j = 0”之外不再有其他日志;当遇到 continue loop1 时,外部循环的执行在下一次迭代中继续,因此只跳过“i = 1, j = 1”和“i = 1, j = 2”。

使用带标签的 continue 语句

给定一个项目数组和测试数组,此示例计算通过所有测试的项目数。

js
// Numbers from 1 to 100
const items = Array.from({ length: 100 }, (_, i) => i + 1);
const tests = [
  { pass: (item) => item % 2 === 0 },
  { pass: (item) => item % 3 === 0 },
  { pass: (item) => item % 5 === 0 },
];
let itemsPassed = 0;

itemIteration: for (const item of items) {
  for (const test of tests) {
    if (!test.pass(item)) {
      continue itemIteration;
    }
  }

  itemsPassed++;
}

请注意 continue itemIteration; 语句如何跳过当前项目的所有剩余测试以及更新 itemsPassed 计数器的语句,并继续处理下一个项目。如果不使用标签,则需要使用布尔标志代替。

js
// Numbers from 1 to 100
const items = Array.from({ length: 100 }, (_, i) => i + 1);
const tests = [
  { pass: (item) => item % 2 === 0 },
  { pass: (item) => item % 3 === 0 },
  { pass: (item) => item % 5 === 0 },
];
let itemsPassed = 0;

for (const item of items) {
  let passed = true;
  for (const test of tests) {
    if (!test.pass(item)) {
      passed = false;
      break;
    }
  }
  if (passed) {
    itemsPassed++;
  }
}

使用带标签的 break 语句

给定一个项目数组和测试数组,此示例确定所有项目是否都通过所有测试。

js
// Numbers from 1 to 100
const items = Array.from({ length: 100 }, (_, i) => i + 1);
const tests = [
  { pass: (item) => item % 2 === 0 },
  { pass: (item) => item % 3 === 0 },
  { pass: (item) => item % 5 === 0 },
];
let allPass = true;

itemIteration: for (const item of items) {
  for (const test of tests) {
    if (!test.pass(item)) {
      allPass = false;
      break itemIteration;
    }
  }
}

同样,如果不使用标签,则需要使用布尔标志代替。

js
// Numbers from 1 to 100
const items = Array.from({ length: 100 }, (_, i) => i + 1);
const tests = [
  { pass: (item) => item % 2 === 0 },
  { pass: (item) => item % 3 === 0 },
  { pass: (item) => item % 5 === 0 },
];
let allPass = true;

for (const item of items) {
  let passed = true;
  for (const test of tests) {
    if (!test.pass(item)) {
      passed = false;
      break;
    }
  }
  if (!passed) {
    allPass = false;
    break;
  }
}

使用带标签的块与 break

你可以标记循环以外的语句,例如简单的块,但只有 break 语句可以引用非循环标签。

js
foo: {
  console.log("face");
  break foo;
  console.log("this will not be executed");
}
console.log("swap");

// Logs:
// "face"
// "swap"

带标签的函数声明

标签只能应用于语句,而不是声明。有一个旧语法允许在非严格代码中标记函数声明

js
L: function F() {}

但是,在严格模式代码中,这会抛出SyntaxError

js
"use strict";
L: function F() {}
// SyntaxError: functions cannot be labelled

非普通函数,例如生成器函数异步函数,既不能在严格代码中标记,也不能在非严格代码中标记

js
L: function* F() {}
// SyntaxError: generator functions cannot be labelled

带标签的函数声明语法已弃用,即使在非严格代码中也不应使用。你实际上无法在函数体中跳转到此标签。

规范

规范
ECMAScript® 2026 语言规范
# sec-labelled-statements

浏览器兼容性

另见