JavaScript's forEach Loop Can't Be Stopped With a Break?

It's true - it's the simplest thing but I had never come across it until recently!

JavaScript’s forEach() method is one of many ways to iterate over Arrays and in my opinion reads a little cleaner than a for() loop. However, it's not very useful if you need to conditionally exit before interating over everything in the Array.

Take a look at the code below:

// Array of stuff
const items = ['a', 'b', 'c', 'd'];

// Clean, elegant
items.forEach((item) => {
  console.log(item);
  // It won't exit the loop
  if(item == 'c'){
    // This will throw an error: Illegal break statement
    break;
    // This does nothing to stop the interation
    return;
  }
});

Why Does This Happen?

The break statement isn't design to be used inside forEach() and return doesn't work because the function we pass into forEach() is actually a callback function so it doesn't affect the forEach() interator. If you look in the MDN docs you'll find: There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool.

The Solution

Use the classic for() loop. It's not the prettiest or latest but it works perfectly for conditional exits and is reportedly faster than forEach().

// Perhaps less elegant but reliable
for(let i = 0; i < items.length; i++){
  console.log(items[i]);
  
  if(items[i] == 'b'){
    // Stops at 'b' then exits loop
    break;
    // or you can return; same result
    return;
  }
}

To keep things consistent for myself I'm going to stick to the trusty for() loop in most cases, whether I need a conditional exit or not. It offers greater flexibility, speed and has been around since JavaScript was first released.

If you want to geek out more on JavaScript loops here are some good resources I found: