ラベル

ラベル付き文は、任意のに接頭辞として識別子を付けたものです。ラベル付き文の中にネストされた 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

関連情報