Loop Control

Control loop execution with break, continue, and labels.

break

Exit a loop immediately. Stop iterating.

The break statement terminates the current loop entirely. Execution jumps to the first statement after the loop.

for (let i = 0; i < 10; i++) {
  if (i === 5) break;  // ← exit here
  console.log(i);
}
// Output: 0, 1, 2, 3, 4
// (5 through 9 never execute)
5
0
1
2
3
4
6
7
8
9
Output: 0, 1, 2, 3, 4
// Search and stop when found:
const users = ["Alice", "Bob", "Charlie", "Dave"];
let found = null;

for (const user of users) {
  if (user === "Charlie") {
    found = user;
    break; // No need to check the rest
  }
}
console.log(found); // "Charlie"

Use break to stop searching once you've found what you need. More efficient than checking all items.

1 / 2

continue

Skip the current iteration. Move to the next one.

The continue statement skips the rest of the current iteration and jumps to the next one (including the update expression in for loops).

for (let i = 0; i < 8; i++) {
  if (i === 3) continue; // ← skip this one
  console.log(i);
}
// Output: 0, 1, 2, 4, 5, 6, 7
// (3 is skipped, but loop continues)
3
0
1
2
3
4
5
6
7
Output: 0, 1, 2, 4, 5, 6, 7

🛑

break

Exit loop completely

No more iterations

⏭️

continue

Skip this iteration

Loop keeps going

// Skip even numbers:
for (let i = 0; i < 10; i++) {
  if (i % 2 === 0) continue;
  console.log(i); // 1, 3, 5, 7, 9
}

// Skip empty values:
const items = ["apple", "", "banana", null, "cherry"];
for (const item of items) {
  if (!item) continue; // skip falsy values
  console.log(item);   // apple, banana, cherry
}

Labels

Break or continue outer loops from inside nested loops.

Normally, break and continue only affect the innermost loop. Labels let you target an outer loop.

// Label syntax:
labelName: for (...) {
  for (...) {
    break labelName;    // exits the OUTER loop
    continue labelName; // skips to next OUTER iteration
  }
}
// Find first pair that sums to 10:
outer: for (let i = 0; i < 5; i++) {
  for (let j = 0; j < 5; j++) {
    if (i + j === 10) {
      console.log(i, j);
      break outer; // exit BOTH loops
    }
  }
}

Without the label, break would only exit the inner loop. The outer loop would keep running.

💡 break outer exits BOTH loops at once
1 / 2
outer:for (let i = 0; i < 3; i++)
for (let j = 0; j < 3; j++)
break→ exits inner only
break outer→ exits both loops

⚠️ Labels are rarely needed. Most cases can be solved by extracting logic into a function and using return instead. Use labels sparingly.

Common Patterns

Real-world uses of break and continue.

1. Early Exit — Find First Match

function findUser(users, id) {
  for (const user of users) {
    if (user.id === id) return user; // break + return
  }
  return null;
}

Return from a function acts like break — exits the loop and the function.

2. Filter with continue

const numbers = [1, -2, 3, -4, 5, -6];
const positives = [];

for (const num of numbers) {
  if (num < 0) continue; // skip negatives
  positives.push(num);
}
// positives = [1, 3, 5]

Skip unwanted items early, keeping the main logic clean and unindented.

3. Limit Results

const results = [];
for (const item of hugeDataset) {
  if (matches(item)) {
    results.push(item);
  }
  if (results.length >= 10) break; // stop after 10
}

Don't process the entire dataset when you only need the first N results.

4. Retry with Break

const MAX_RETRIES = 3;
let success = false;

for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
  try {
    await fetchData();
    success = true;
    break; // success! stop retrying
  } catch (err) {
    console.log(`Attempt ${attempt} failed`);
  }
}

Try up to N times, stop as soon as one succeeds.

Frequently Asked Questions

Common questions about loop control.