Labeled statement
=================

A **labeled statement** is any statement that is prefixed with an identifier. You can jump to this label using a `break` or `continue` statement nested within the labeled statement.

Try it
------

Syntax
------


```js
label:
  statement
```


`label`

Any JavaScript identifier that is not a reserved word.

`statement`

A JavaScript statement. `break` can be used within any labeled statement, and `continue` can be used within labeled looping statements.

Description
-----------

You can use a label to identify a statement, and later refer to it using a `break` or `continue` statement. Note that JavaScript has *no* `goto` statement; you can only use labels with `break` or `continue`.

Any `break` or `continue` that references `label` must be contained within the `statement` that's labeled by `label`. Think about `label` as a variable that's only available in the scope of `statement`.

If a `break label;` statement is encountered when executing `statement`, execution of `statement` terminates, and execution continues at the statement immediately following the labeled statement.

`continue label;` can only be used if `statement` is one of the looping statements. If a `continue label;` statement is encountered when executing `statement`, execution of `statement` continues at the next iteration of the loop. `continue;` without a label can only continue the innermost loop, while `continue label;` allows continuing any given loop even when the statement is nested within other loops.

A statement can have multiple labels. In this case, the labels are all functionally equivalent.

Examples
--------

### Using a labeled continue with for loops


```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
```


Notice how it skips both "i = 1, j = 1" and "i = 1, j = 2".

### Using a labeled break with for loops


```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
```


Notice the difference with the previous `continue` example: when `break loop1` is encountered, the execution of the outer loop is terminated, so there are no further logs beyond "i = 1, j = 0"; when `continue loop1` is encountered, the execution of the outer loop continues at the next iteration, so only "i = 1, j = 1" and "i = 1, j = 2" are skipped.

### Using a labeled continue statement

Given an array of items and an array of tests, this example counts the number of items that pass all the tests.


```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++;
}
```


Note how the `continue itemIteration;` statement skips the rest of the tests for the current item as well as the statement that updates the `itemsPassed` counter, and continues with the next item. If you don't use a label, you would need to use a boolean flag instead.


```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++;
  }
}
```

### Using a labeled break statement

Given an array of items and an array of tests, this example determines whether all items pass all tests.


```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;
    }
  }
}
```


Again, if you don't use a label, you would need to use a boolean flag instead.


```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;
  }
}
```

### Using a labeled block with break

You can label statements other than loops, such as simple blocks, but only `break` statements can reference non-loop labels.


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

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

### Labeled function declarations

Labels can only be applied to statements, not declarations. There is a legacy grammar that allows function declarations to be labeled in non-strict code:


```js
L: function F() {}
```


In strict mode code, however, this will throw a `SyntaxError`:


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


Non-plain functions, such as generator functions and async functions can neither be labeled in strict code, nor in non-strict code:


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


The labeled function declaration syntax is deprecated and you should not use it, even in non-strict code. You cannot actually jump to this label within the function body.

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-labelled-statements |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `break`
* `continue`