Lesson 72 of 80
break and continue can target a labeled outer loop by name, escaping nested loops in one step — rare in the wild, but a real tool, not a curiosity.
10 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
break and continue normally act on the nearest enclosing loop. A label gives an outer loop a name, so break label; or continue label; can reach past inner loops and act on that specific one instead. It's the one place JavaScript lets you jump out of more than one level of nesting in a single statement.
Most developers go years without writing one, and that's fine — labels solve a narrow problem (escaping nested loops cleanly) that usually has a decent alternative. But "rare" isn't "wrong," and reading one in someone else's code shouldn't be confusing.
Say you're searching a 2D grid for the first cell that matches a target, and you want to stop both loops the instant you find it:
function findFirstMatch(grid, target) {
let found = null;
outer: for (let row = 0; row < grid.length; row++) {
for (let col = 0; col < grid[row].length; col++) {
if (grid[row][col] === target) {
found = [row, col];
break outer; // exits BOTH loops, not just the inner one
}
}
}
return found;
}
Without the label, a plain break only exits the inner for loop — the outer loop would keep running and re-enter the inner loop on the next row. You'd need a separate flag variable (let stop = false; checked in the outer loop's condition) to actually escape both. The label does that in one word.
continue label; works the same way, skipping to the next iteration of the labeled loop rather than the innermost one:
search: for (const row of grid) {
for (const cell of row) {
if (cell < 0) continue search; // skip the rest of this row, move to the next
process(cell);
}
}
return to escape is usually clearer than a label, because "exit this function" is a more familiar signal than "exit this specific labeled loop." Reach for a label when extracting a function would be awkward (e.g. it needs to update several local variables the caller cares about).myBlock: { ... }) and break myBlock; to jump past it — useful for a series of sequential checks where you want an early exit without nested ifs. This is rarer still, but valid.Labels are pure control flow, sitting next to break, continue, and return rather than anything about how loops iterate. The reason they feel unfamiliar is the same reason a flag-variable approach or a function-with-early-return usually wins in real codebases: JavaScript style has generally favored structuring code so you rarely need to escape more than one level of nesting at once, in the same way generator functions favor yield-based control flow over manual state machines.