Command Palette

Search for a command to run...

Hectal
PHASE 2Beginner ~21 min· topic 6 of 7

Topic 2.6

break, continue and Labels

In one line

break leaves a loop (or switch) immediately, continue skips the rest of the current iteration and moves on to the next one, and a label lets either of them act on an outer loop instead of the innermost one.

Think of it like this

Looking for your keys in a row of drawers. As soon as you find them, you stop searching: that's break. If a drawer is locked, you skip it and move to the next one: that's continue. Now imagine a cupboard with several shelves of drawers. Finding the keys should stop the search of the whole cupboard, not only the current shelf: that's a break with a label.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

break
A statement that leaves the current loop or switch immediately.
continue
A statement that skips the rest of this iteration and goes on to the next one.
Label
A name with a colon (outer:) put before a loop, so break or continue can refer to that loop.
Innermost loop
In nested loops, the loop that most directly contains the statement.
Early exit
Leaving a loop or function as soon as the answer is known, instead of finishing all the work.
Callback
A function you hand to another function to call for you, like the one passed to forEach.

Step by step

01Stop early with break

Search until you find a match, then stop. The lines after the loop run straight away.

break.jswhole filejavascript
const scores = [40, 72, -1, 88];
for (const s of scores) {
  if (s < 0) {
    console.log("Bad score found:", s);
    break;
  }
  console.log("ok", s);
}
// ok 40, ok 72, Bad score found: -1  (88 is never checked)

02Skip items with continue

continue jumps to the next item. Everything below it in the body is skipped for this item only.

continue.jswhole filejavascript
const names = ["Asha", "", "Ravi", ""];
for (const name of names) {
  if (name === "") continue;
  console.log("Hello", name);
}

03See where each one jumps

In a for loop, continue goes to the update step; break goes past the end of the loop.

See where each one jumpsdiagram
Rendering diagram…

04Leave nested loops with a label

A plain break in the inner loop only stops the inner loop. Label the outer loop and break outer stops both.

label.jswhole filejavascript
outer: for (let row = 0; row < 3; row++) {
  for (let col = 0; col < 3; col++) {
    if (row * col === 2) {
      console.log("found at", row, col);
      break outer;
    }
  }
}

05Prefer clearer tools when they fit

Labels work, but moving the nested search into a function and using return is often clearer. For arrays, find and some stop early on their own (Phase 5).

Try it yourself

  1. 1

    Swap break and continue

    In the first example, change break; to continue;. Predict which items appear on the page now. (milk, bread, eggs, chips, cola: STOP is skipped instead of ending the loop.)

  2. 2

    Change the target

    In the second example, set target to 2. Predict both checks numbers before running. (9 and 9: the only 2 is the last cell.)

  3. 3

    Remove the label

    In the third example, change break loop; to break;. Predict the final total. (3: the last add still runs.)

Code & diagrams

break and continue in a shopping list New tab

Empty entries are skipped with `continue`; `STOP` ends the loop with `break`, so chips and cola never appear.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

skip empty at 1
skip empty at 3
break at 5
items on the page: 3
Labels: leaving nested loops New tab

The plain `break` finds the 7 in row 1, leaves the inner loop, and then row 2 is searched too. `break search` stops the whole search.

Console

(nothing was printed)

Expected console output

found 7 at row 1 col 1
found 7 at row 2 col 1
checks without label: 7
found 7 at row 1 col 1
checks with label: 5
break inside a switch inside a loop New tab

A plain `break` in a `switch` only leaves the switch. `continue rows` skips straight to the next row, so only row 3 reaches its last line.

Console

(nothing was printed)

Expected console output

quit seen, total so far: 2
final total: 2
row 3 complete: 123

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

break inside forEach

Write [1, 2, 3].forEach((n) => { if (n === 2) break; console.log(n); });.

terminal
$ Console
── what you'll see ──
Uncaught SyntaxError: Illegal break statement

Break #2

continue skips the update in a while loop

Write let i = 0; while (i < 5) { if (i === 2) continue; console.log(i); i++; }.

terminal
$ Browser
── what you'll see ──
Prints 0 and 1, then the page freezes: i stays 2 forever.

Myth vs fact

Myth

break leaves all the loops it's inside.

Fact

It leaves only the innermost loop or switch. Use a label, a flag variable, or a function with return to leave more than one.

Myth

Labels are like goto and should never be used.

Fact

They can only exit or continue an enclosing statement; they can't jump anywhere else. For breaking out of nested loops they're the clearest built-in tool. Just don't overuse them.

Myth

return inside forEach stops the loop.

Fact

It only ends the callback for the current item; forEach then calls it for the next one. It works like continue, not break.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    In the spec, break and continue produce abrupt completions carrying an optional label. Each loop checks whether the completion's label is in its own label set; if not, it passes the completion outward. That's the whole mechanism behind labelled jumps, and it's why continue label must name an enclosing loop (SyntaxError: Illegal continue statement: 'x' does not denote an iteration statement).

  • ▸

    Breaking out of a for...of loop calls the iterator's return() method, so generators and other iterators get a chance to clean up (close a file, release a lock). You'll see this with iterators and generators in Phase 14.

  • ▸

    Early exit is often the biggest performance win in search code: linear search with break does, on average, half the work when the item is present. Hectal's /dsa course builds on this idea with binary search and two pointers.

  • ▸

    Linters such as ESLint have no-labels and no-continue rules that some teams enable. Treat them as style choices: a well-placed continue usually reads better than a deeply nested if.

Remember this

  1. 1

    **break** ends the innermost enclosing loop (for, while, do...while, for...of, for...in) or switch straight away. Execution continues with the first statement after that loop. Use it to stop early when you've found what you were looking for, or when continuing makes no sense (an error, a limit reached). Stopping early is also faster: a search that finds its answer at item 3 doesn't need to look at the other 997.

  2. 2

    **continue ends only the current iteration**. The rest of the body is skipped, and the loop moves to its next step: in a for loop, the update (i++) runs and then the condition is checked; in while and do...while, it jumps straight to the condition check. Use it to skip items that don't qualify (empty values, invalid input) without wrapping the rest of the body in an if. It's the loop version of a guard clause (Topic 2.3).

  3. 3

    Both act only on the innermost loop. In nested loops, break in the inner loop leaves only the inner loop: the outer loop carries on with its next iteration. A break inside a switch that is inside a loop leaves the switch, not the loop, which surprises many people.

  4. 4

    A label is a name followed by a colon, written right before a statement: outer: for (...) { ... }. Then break outer; leaves the labelled loop entirely, and continue outer; jumps to the next iteration of the labelled loop, from anywhere inside it. Labels are rare in everyday code, but they're the cleanest way to exit two nested loops at once. break label also works on a labelled plain block { }; continue label only works on loops.

  5. 5

    **break and continue only work in loops and switch**, not inside callback functions. array.forEach(x => { break; }) is a SyntaxError ("Illegal break statement"): the arrow function is a separate function, so there is no loop around the break from its point of view. If you need to stop early, use a for or for...of loop, or an array method made for it such as find, some or every (Phase 5). return inside a function also leaves any loop it's in, since it leaves the whole function.

  6. 6

    A common continue trap: in a while loop where the counter is updated at the end of the body, continue skips that update, and the loop never ends. In a for loop this can't happen, because the update lives in the header and always runs. When you use continue in a while, update the counter before the continue.

Explain it without notes

01

What is the difference between break and continue?

02

What does a plain break do inside nested loops, and how do you leave both loops?

03

Why can't you use break inside forEach?

Practice

01

Loop over [5, 12, 8, 130, 44] and print the first number greater than 100, then stop.

02

Print every number from 1 to 10 except multiples of 3, using continue.

Trade-offs

  • ↔

    continue and break flatten loop bodies but add jumps a reader must follow; a few are fine, many in one loop make it hard to see what runs.

  • ↔

    Labels exit nested loops in one line; extracting the search into a function with return is often easier to read and test.

Done when you can

  • I can use break to stop a loop early.

  • I can use continue to skip items.

  • I know break only leaves the innermost loop or switch.

  • I can use a label to leave or continue an outer loop.

  • I know break doesn't work inside forEach, and what to use instead.