ラベル

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

ラベル付き文は、任意のに接頭辞として識別子を付けたものです。ラベル付き文の中にネストされた break 文や continue 文を使用すると、このラベルにジャンプすることができます。

試してみましょう

構文

js
ラベル:
  文
ラベル

予約語ではない任意の JavaScript の識別子

JavaScript の文。 break は任意のラベル付き文で使うことができ、 continue はループのラベル付き文で使うことができます。

解説

ラベルを使用して文を識別すると、後で break または continue 文を使用して参照することができます。JavaScript には goto 文がないことに注意してください。

ラベルを参照する breakcontinue は、ラベル によってラベル付けされた 中になければなりません。ラベル は、 の範囲内でしか利用できない変数だと考えてください。

もし、 を実行中に break ラベル; 文に出会った場合、 の実行が終了し、ラベル付けされた文の直後の文から実行を続けます。

continue ラベル; は、ループ文のうちの何れかである場合のみ使用できます。continue ラベル; 文が の実行中に現れた場合、 の実行はループの次の反復処理に続きます。ラベルなしの continue; は最も内側のループのみを継続することができるのに対し、continue ラベル; はその文がほかのループの中にネストされていた場合でも、指定した任意のループの継続処理を行うことができます。

文に複数のラベルを付けることができます。この場合、ラベルはすべて機能的に同等になります。

ラベル付き continue を for ループで使用

js
// 最初の文は "loop1" というラベルが付いています
loop1: for (let i = 0; i < 3; i++) {
  // 2 番目の文は "loop2" というラベルが付いています
  loop2: for (let j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      continue loop1;
    }
    console.log(`i = ${i}, j = ${j}`);
  }
}

// 結果:
// 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" をスキップしていることに注目してください。

ラベル付き break を for ループで使用

js
let i, j;

// 1 番目の for 文に "loop1" というラベルを付ける
loop1: for (i = 0; i < 3; i++) {
  // 2 番目の for 文に "loop2" というラベルを付ける
  loop2: for (j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      break loop1;
    }
    console.log(`i = ${i}, j = ${j}`);
  }
}

// 結果:
// 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" だけスキップされます。

ラベル付き continue 文の使用

配列 items と tests について、この例はすべてを tests に渡した items の数を数えます。

js
// 1 から 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
// 1 から 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 文を使用する

配列 items と tests について、このサンプルは items のすべてを tests に渡したかを判断します。

js
// 1 から 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
// 1 から 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

ラベル付きの関数電源の構文は非推奨であり、厳格モードでないコードであっても使用すべきではありません。実際、関数の本体の中からこのラベルへジャンプすることはできません。

仕様書

Specification
ECMAScript Language Specification
# sec-labelled-statements

ブラウザーの互換性

BCD tables only load in the browser

関連情報