JavaScriptLabels

Labels

A label is an identifier with a colon attached to a statement — usually a loop. Once a statement is labelled, you can break or continue to that exact label from anywhere inside it, including from nested loops. Labels are the only built-in way to break out of an outer loop in JavaScript, but most code shouldn't need them.

Syntax

JS
outer: for (let r = 0; r < rows; r++) {
  for (let c = 0; c < cols; c++) {
    if (grid[r][c] === target) {
      break outer;        // exits the loop named "outer"
    }
  }
}

The label is just a name — pick something descriptive. Common choices: outer, rows, scan, search. Labels live in their own namespace, so you can reuse names that exist as variables without conflict, though it's not a habit to cultivate.

Labelled break

break label jumps to the statement after the labelled statement. The most common use is escaping a nested search.

JS
function findPair(matrix, target) {
  let found = null;

  search: for (let r = 0; r < matrix.length; r++) {
    for (let c = 0; c < matrix[r].length; c++) {
      if (matrix[r][c] === target) {
        found = [r, c];
        break search;
      }
    }
  }

  return found;
}

console.log(findPair([[1, 2], [3, 4]], 3));
[ 1, 0 ]
Labelled continue

continue label jumps to the next iteration of the labelled loop, skipping the rest of every enclosed loop. It's rarer but occasionally exactly what you want.

JS
const grid = [
  [1, 2, 3],
  [4, -1, 6],
  [7, 8, 9],
];

rows: for (let r = 0; r < grid.length; r++) {
  for (let c = 0; c < grid[r].length; c++) {
    if (grid[r][c] < 0) continue rows;    // abandon this whole row
    process(grid[r][c]);
  }
}

Without the label, continue would only skip to the next column. The label lets us say "drop the row and move on".

Labels can attach to any statement

Technically you can label any statement, not just loops — including a plain block. Once labelled, break label exits the block.

JS
done: {
  if (!user) break done;
  if (!user.active) break done;
  charge(user);
  notify(user);
}

This is sometimes called a "labelled block" pattern — a structured-goto style. It works, but it's almost always clearer as guard clauses inside a function with return.

When (rarely) labels are useful
  • Deeply nested numeric loops where extracting a function would obscure the algorithm — game grids, image processing, dynamic programming inner loops.

  • Code that genuinely needs to continue an outer loop based on a condition discovered in an inner one.

  • Performance-critical hot loops where extracting a function would add call overhead — but measure before assuming.

Why most code shouldn't use them

Labels are unusual in modern JavaScript. Most readers have rarely or never seen one. The same job can almost always be done with one of these:

  • Extract a function and use return — the cleanest fix, and the one that signals intent.

  • Set a flag and check it in the outer loop's condition. Slightly verbose but obvious.

  • Throw a sentinel error — heavy-handed, but works for very deep nesting if a function refactor is impossible.

  • Use array methods like find, some, findIndex — they break early by design.

The labelled version

JS
outer: for (const row of matrix) {
  for (const value of row) {
    if (value === target) {
      console.log("found");
      break outer;
    }
  }
}

The refactored version most teams prefer

JS
function contains(matrix, target) {
  for (const row of matrix) {
    if (row.includes(target)) return true;
  }
  return false;
}

if (contains(matrix, target)) console.log("found");
Reach for them last
Labelled break is a perfectly valid feature, not a smell — but it surprises readers and confuses tools. Use it only when the refactor would genuinely make code worse, and document with a comment why a plain function or flag wasn't enough.
What labels are not

Labels are not goto. You cannot break to a label that comes after the current position; the label has to enclose the break. You also can't jump into an arbitrary point in code. JavaScript deliberately left that out — and the language is healthier for it.

One sentence to remember
Labels let you `break` or `continue` an outer loop from a nested one — they work, they're standard, and you should almost always reach for a small function with `return` first.