JavaScript Break and Continue Get Certified
The break and continue statements give
you extra control over how a loop runs. They let you exit a loop
early or skip specific iterations without needing extra
conditions wrapped around the entire loop body.
In this lesson, you will learn how break and
continue work, how to use labels to control nested
loops, and how to avoid some common mistakes.
The break Statement
The break statement immediately exits the loop it is
inside, skipping any remaining iterations entirely.
What this code does: break exits the loop immediately.
When i reaches 4, the loop stops, so only 1, 2, and 3 are printed, then “Loop ended.”
for (let i = 1; i <= 10; i++) {
if (i === 4) {
break;
}
console.log(i);
}
console.log("Loop ended.");
for (let i = 1; i <= 10; i++) { would normally count from 1 to 10. The break inside the body will end it earlier, so not all ten passes will happen.if (i === 4) { tests on every pass whether the counter has reached 4. The === operator checks that the value and the type are both equal. For 1, 2 and 3 the condition is false, so the if block is skipped.break; runs only when i is 4. It ends the whole loop immediately, even though i <= 10 is still true. JavaScript jumps to the first line after the loop’s closing brace.} closes the if block that began on line 2.console.log(i); runs on passes 1, 2 and 3 only. On pass 4 the break happens before this line is reached, so 4 is not printed.} ends the loop body. The values 5 to 10 are never checked, because the loop was stopped by break.break. The full output is 1, 2, 3 and then Loop ended.
Once i reaches 4, the loop stops
completely — the remaining values (5 through 10) are never
checked.
break in a while Loop
break works the same way in while and
do...while loops.
What this code does: A common pattern: an intentional infinite while (true)
that stops with break when a condition is met. Here it prints 1, 2, 3 then exits.
let i = 0;
while (true) {
i++;
if (i > 3) {
break;
}
console.log(i);
}
let i = 0; creates the counter i and sets it to 0.while (true) { uses the value true as the condition. Since true is always true, this loop would run forever if nothing stopped it. Here that is intentional: the loop will be ended from the inside with break.i++; adds 1 to i. It comes first in the body, so the first pass works with i equal to 1.if (i > 3) { is the exit test. It is false for 1, 2 and 3, and becomes true when i is 4.break; leaves the while (true) loop immediately. This is the only way out of the loop. It runs when i is 4.} closes the if block that began on line 4.console.log(i); is reached only while i is 3 or less, so it prints 1, 2 and 3. On the fourth pass, break happens first.} ends the loop body. Without the if and break above, this code would never stop and would freeze the browser tab.
Here, while (true) would normally run forever, but
break gives us a controlled way to exit once a
condition is met.
break in a switch Statement
break is also used inside a switch
statement to stop it from falling through into the next case.
What this code does: In a switch, break prevents fall-through to the next case.
Matching “green” prints “Go!” and then leaves the switch.
let color = "green";
switch (color) {
case "red":
console.log("Stop!");
break;
case "green":
console.log("Go!");
break;
default:
console.log("Unknown color.");
}
let color = "green"; stores the string "green", like the colour of a traffic light. The switch will compare this value with each case.switch (color) { evaluates color once and compares it with the case labels below, from top to bottom, using strict equality (===).case "red": checks "green" === "red", which is false, so this case is skipped."Stop!" when the colour is red. It is skipped here.break would end the switch after the red code. It is never reached here.case "green": checks "green" === "green", which is true. JavaScript starts running the code under this label.Go!. This is the output of the program.break; exits the switch immediately, so the code under default does not run. Without it, execution would fall through into the next case and also print Unknown color.default: marks the code that runs when no case matches, for example for "blue".Unknown color. for an unlisted colour. It is skipped because green matched, and break already ended the switch.} ends the switch block. The output is Go!.The continue Statement
The continue statement skips the rest of the current
iteration and jumps straight to the next one. Unlike
break, it does not stop the loop entirely.
What this code does: continue skips the rest of the current iteration.
Multiples of 3 are skipped, so 1, 2, 4, 5, 7, 8, 10 are printed.
for (let i = 1; i <= 10; i++) {
if (i % 3 === 0) {
continue;
}
console.log(i);
}
for (let i = 1; i <= 10; i++) { runs the body once for each number from 1 to 10. Unlike break, continue will not stop this loop; it only skips some passes.if (i % 3 === 0) { uses the remainder operator %. i % 3 is the remainder after dividing by 3, which is 0 for 3, 6 and 9. So the condition is true only for multiples of 3.continue; stops the current pass immediately and jumps to the update (i++), then to the next pass. The console.log line below is skipped for this value of i, but the loop carries on.} closes the if block that began on line 2.console.log(i); is reached by every number that is not a multiple of 3. The output is 1, 2, 4, 5, 7, 8, 10. The values 3, 6 and 9 are skipped.} ends the loop body. After the pass with i equal to 10, the counter becomes 11 and the loop ends normally. Compare this with break, which would have ended the loop completely at 3.This loop skips every multiple of 3, but continues checking the remaining numbers all the way up to 10.
continue in a while Loop
When using continue in a while loop, be
careful that the update expression still runs before
continue, or the loop may never end.
What this code does: In a while loop, continue jumps back to the condition check.
Even numbers are skipped after incrementing, so only the odd numbers 1, 3, 5, 7, 9 are printed.
let i = 0;
while (i < 10) {
i++;
if (i % 2 === 0) {
continue;
}
console.log(i);
}
let i = 0; creates the counter and sets it to 0.while (i < 10) { keeps the loop running while i is less than 10. Unlike a for loop, a while loop has no built-in update, so the counter must be updated inside the body.i++; increases i at the top of the body, so the first pass works with i equal to 1. This position is important: because the update happens before continue, it is never skipped. If it were placed after continue, even numbers would skip the update, i would never change again and the loop would run forever.if (i % 2 === 0) { uses the remainder operator %. i % 2 is 0 for even numbers, so this condition is true for 2, 4, 6, 8 and 10.continue; ends the current pass immediately and jumps back to the while condition on line 2. In a while loop, continue goes straight to the condition check (there is no update expression to run). The console.log line below is skipped for even numbers.} closes the if block that began on line 4.console.log(i); is only reached by odd numbers. The output is 1, 3, 5, 7, 9.} ends the loop body and returns to the condition. After i reaches 10 (even, so skipped), the condition 10 < 10 is false and the loop ends.
Because i++ runs before the continue
check, the loop variable is always updated, avoiding an infinite
loop.
break vs. continue
| Aspect | break | continue |
|---|---|---|
| Effect on the loop | Exits the loop entirely | Skips to the next iteration |
| Remaining iterations | Never run | Still run, except the skipped one |
| Also usable in switch? | Yes | No (only in loops) |
Labeled Statements
By default, break and continue only
affect the loop they are directly inside. A label
lets you target an outer loop from within a nested loop.
A label is written as a name followed by a colon, placed directly before the loop it identifies.
What this code does: A labeled break can exit an outer loop from inside a nested loop.
When j === 2, break outerLoop stops both loops at once. Only “i=1, j=1” is printed.
outerLoop:
for (let i = 1; i <= 3; i++) {
for (let j = 1; j <= 3; j++) {
if (j === 2) {
break outerLoop;
}
console.log("i=" + i + ", j=" + j);
}
}
outerLoop: is a label: a name followed by a colon, placed directly before the loop it identifies. Here it gives the name outerLoop to the for loop that starts on the next line. A label does nothing by itself; it only lets break or continue refer to that loop by name.for (let i = 1; i <= 3; i++) { is the labeled outer loop. It would normally run three times, with i equal to 1, 2 and 3.for (let j = 1; j <= 3; j++) { is the inner loop. For each pass of the outer loop, it would normally run three times, with j equal to 1, 2 and 3.if (j === 2) { is true as soon as the inner loop reaches its second pass.break outerLoop; does not just leave the inner loop: it ends the loop named outerLoop, so both loops stop at once. A plain break; here would end only the inner loop and the outer loop would continue with i equal to 2.} closes the if block that began on line 4.+. It runs only on the first pass of the inner loop (j is 1), because on the next pass the labeled break fires. The only output is i=1, j=1.} (indented four spaces) closes the inner loop. It is never reached a second time here, because break outerLoop ended everything.} at the left margin closes the outer loop. The values i = 2 and i = 3 are never reached. Try replacing break outerLoop; with a plain break; in the editor to compare: you will get i=1, j=1, i=2, j=1 and i=3, j=1.
Without the label, break would only stop the inner
loop, and the outer loop would continue running. With
break outerLoop;, both loops stop immediately.
Labeled continue
A label can also be used with continue to skip to
the next iteration of an outer loop instead of the inner one.
What this code does: A labeled continue skips to the next iteration of the outer loop.
When j === 2, the rest of that row is skipped and the outer loop moves to the next i.
outerLoop:
for (let i = 1; i <= 3; i++) {
for (let j = 1; j <= 3; j++) {
if (j === 2) {
continue outerLoop;
}
console.log("i=" + i + ", j=" + j);
}
}
outerLoop: is a label for the for loop on the next line. It lets continue refer to that outer loop by name.for (let i = 1; i <= 3; i++) { is the labeled outer loop. It runs three times, with i equal to 1, 2 and 3. This time all three passes will happen.for (let j = 1; j <= 3; j++) { is the inner loop. It starts again from j = 1 every time the outer loop begins a new pass.if (j === 2) { becomes true on the second pass of the inner loop, in every outer pass.continue outerLoop; abandons the rest of the inner loop and jumps to the next pass of the outer loop (running its update i++). A plain continue; would only skip to the next j, so j = 3 would still be printed.} closes the if block that began on line 4.j is 1, because on j equal to 2 the labeled continue jumps away. j = 3 is never reached. The output is i=1, j=1, i=2, j=1 and i=3, j=1.} (indented four spaces) closes the inner loop.} closes the outer loop. Compare this with the previous example: break outerLoop stopped everything after one line, while continue outerLoop keeps the outer loop going and prints one line for each value of i.
Here, as soon as j reaches 2, the inner
loop is abandoned and control jumps straight to the next
iteration of the outer loop, incrementing i.
Practical Example
Let’s use break and continue together
to search for a specific value in a nested list, stopping as soon
as it’s found.
What this code does: A practical search in a 2D grid. When the target value is found,
a labeled break exits both loops immediately instead of continuing to scan the rest of the grid.
const grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
const target = 6;
let found = false;
search:
for (let row = 0; row < grid.length; row++) {
for (let col = 0; col < grid[row].length; col++) {
if (grid[row][col] === target) {
found = true;
console.log("Found " + target + " at row " + row + ", col " + col);
break search;
}
}
}
if (!found) {
console.log(target + " was not found in the grid.");
}
const grid = [ starts an array. This array will contain other arrays, forming a 2D grid (rows and columns).[1, 2, 3], is the first row. It is stored at grid[0].[4, 5, 6], is the second row, stored at grid[1]. The value we are looking for, 6, is in this row.[7, 8, 9] is the third row, stored at grid[2]. It has no comma after it because it is the last item.]; closes the outer array and ends the statement.const target = 6; stores the number to look for.let found = false; is a flag that starts as false. It will be set to true if the target is found, and is checked at the end.search: is a label naming the loop on the next line, so that the inner loop can end it with break search.for (let row = 0; row < grid.length; row++) { visits each row. grid.length is 3, so row goes 0, 1, 2 (array indexes start at 0).for (let col = 0; col < grid[row].length; col++) { visits each value in the current row. grid[row] is the current row array, and .length is how many values it holds.if (grid[row][col] === target) { reads the value at the current row and column (the first index picks the row, the second picks the value in that row) and compares it with the target. It is false for 1, 2, 3, 4 and 5, and true for 6.found = true; sets the flag, so the check at the end knows the search succeeded.+. The target 6 is in the second row (index 1) and the third column (index 2), so the output is Found 6 at row 1, col 2.break search; ends the labeled outer loop, which stops both loops at once. Without the label, break would only leave the inner loop, and the search would needlessly continue with row 2 (7, 8, 9).} closes the if block that began on line 11.} closes the inner (column) loop.} closes the outer (row) loop.if (!found) { runs only if found is still false (! means NOT). That happens when the loops finished without finding the target.6 was not found in the grid.. It is skipped here, since 6 was found. Try changing target to 10 to see this message.} closes the if block that began on line 18.Common Mistakes With break and continue
- Expecting
breakinside a nested loop to stop every loop, when it only stops the innermost one by default. - Placing
continuebefore the loop’s update expression in awhileloop, accidentally creating an infinite loop. - Overusing labels for simple cases where restructuring the loop logic would be clearer.
- Forgetting that
continuecannot be used inside aswitchstatement on its own — it always refers to an enclosing loop. - Using
breakorcontinueoutside of a loop (orswitch, forbreak), which causes a syntax error.
Best Practices for break and continue
- Use
breakto stop searching once you’ve found what you’re looking for, instead of letting the loop run unnecessarily. - Use
continueto skip irrelevant values instead of wrapping the rest of the loop body in anifstatement. - Reserve labeled statements for genuinely nested loop scenarios, and give labels clear, descriptive names.
- Double-check that
continuein awhileloop doesn’t skip a necessary update expression. - Consider extracting complex nested loops into a separate function, which can use
returninstead of a labeledbreak.
Quick Summary
breakexits a loop (orswitch) immediately.continueskips the rest of the current iteration and moves to the next one.- Both statements work in
for,while, anddo...whileloops. - Labels let
breakandcontinuetarget an outer loop from within a nested loop. - A label is written as
labelName:directly before the loop it identifies. - Using these statements thoughtfully can make loops more efficient and easier to read.
Try It Yourself
Modify the code below. Try changing which value triggers
break or continue, and see how the
output changes.
What this code does: Practice example combining both: even numbers are skipped with
continue, and the loop stops at 7 with break. Change the values and click
Test My Code to experiment.
for (let i = 1; i <= 10; i++) {
if (i === 7) {
break;
}
if (i % 2 === 0) {
continue;
}
console.log(i);
}
for (let i = 1; i <= 10; i++) { is the loop that will be controlled by both break and continue. Change the numbers in the conditions below and run the code again to experiment.if (i === 7) { checks whether the counter has reached 7. It is false for 1 to 6.break; ends the whole loop when i is 7, even though the condition i <= 10 is still true. The values 8, 9 and 10 are never reached.} closes the if block that began on line 2.if (i % 2 === 0) { is true for even numbers (2, 4, 6). It is only reached when i is not 7, because break would already have ended the loop.continue; skips the rest of the current pass for even numbers, so they are not printed. The loop itself continues with the next number.} closes the if block that began on line 5.console.log(i); is reached only by odd numbers below 7, so it prints 1, 3 and 5. The number 7 itself is not printed, because the break check comes first.} ends the loop body. The output is 1, 3, 5. Try moving the two if blocks around or changing 7 to 8 to see how the order of the checks matters.Tip: Think ofbreakas “I’m done here, stop everything,” andcontinueas “skip this one, but keep going.” Keeping that distinction clear in your head makes it much easier to predict how a loop will behave.
Understanding break and continue is
useful before moving on to functions, arrays, and more advanced
JavaScript concepts.
🧪 Test Your JavaScript Code
Edit the code on the left and click “Run Code” to see the console output on the right.
Click “Run Code” to see the output here.
Code Explanation
The complete example stays visible. Use Previous and Next to move through its logical blocks.
Select Next to begin exploring the code.