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)// 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.
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)🛑
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.
⚠️ 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.