How to Break Out of a JavaScript forEach() Loop

Oct 5, 2020

JavaScript's forEach() function executes a function on every element in an array. However, since forEach() is a function rather than a loop, using the break statement is a syntax error:

[1, 2, 3, 4, 5].forEach(v => {
  if (v > 3) {
    // SyntaxError: Illegal break statement
    break;
  }
});

We recommend using for/of loops to iterate through an array unless you have a good reason not to. However, if you find yourself stuck with a forEach() that needs to stop after a certain point and refactoring to use for/of is not an option, here's three workarounds:

1. Use every() instead of forEach()

The every() function behaves exactly like forEach(), except it stops iterating through the array whenever the callback function returns a falsy value.

// Prints "1, 2, 3"
[1, 2, 3, 4, 5].every(v => {
  if (v > 3) {
    return false;
  }

  console.log(v);
  // Make sure you return true. If you don't return a value, `every()` will stop.
  return true;
});

With every(), return false is equivalent to a break, and return true is equivalent to a continue.

Another alternative is to use the find() function, which is similar but just flips the boolean values. With find(), return true is equivalent to break, and return false is equivalent to continue.

2. Filter Out The Values You Want to Skip

Instead of thinking about how to break out of a forEach(), try thinking about how to filter out all the values you don't want forEach() to iterate over. This approach is more in line with functional programming principles.

The findIndex() function takes a callback and returns the first index of the array whose value the callback returns truthy for. Then the slice() function copies part of the array.

// Prints "1, 2, 3"
const arr = [1, 2, 3, 4, 5];

// Instead of trying to `break`, slice out the part of the array that `break`
// would ignore.
arr.slice(0, arr.findIndex(v => v > 3)).forEach(v => {
  console.log(v);
});

3. Use a shouldSkip Local Variable

If you can't use every() or slice(), you can check a shouldSkip flag at the start of your forEach() callback. If you set shouldSkip to true, the forEach() callback returns immediately.

// Prints "1, 2, 3"
let shouldSkip = false;
[1, 2, 3, 4, 5].forEach(v => {
  if (shouldSkip) {
    return;
  }
  if (v > 3) {
    shouldSkip = true;
    return;
  }

  console.log(v);
});

This approach is clunky and inelegant, but it works with minimum mental overhead. You can use this approach if the previous approaches seem too clever.


More Fundamentals Tutorials