DEV Community

Cover image for When for...of loop is preferred over forEach
Sharmin
Sharmin

Posted on • Edited on

When for...of loop is preferred over forEach

A while ago, I came across a question from a student who wanted to iterate over numbers in a list and return true if there is a duplicated number.
The code was as follows and the student wondered why it didn't behave as she expected.

function containsDuplicate(nums) {
  const dups = [];
  nums.forEach((num) => {
    if (dups.includes(num)) {
      return true; // Found a duplicate
    }
    dups.push(num);
  });
  return false; // No duplicates found
}
const nums = [1, 2, 3, 3, 5];
console.log(containsDuplicate(nums));
Enter fullscreen mode Exit fullscreen mode

In the above code, ForEach iterates over the numbers and adds the non-duplicated numbers to another list named dups. It will return true as soon as a duplicate is found otherwise it returns false.
It seems pretty straightforward. Doesn't it?
But despite existing duplicates in the array, calling containsDuplicate(nums) returns false.
So why does it happen?
The problem hides behind using return true inside the ForEach loop and expecting it to exit early and return the true value as the result of invoking containsDuplicate(nums). That is a false expectation.

In a forEach loop (or other higher-order functions like map, filter, etc.), a return statement inside the callback function will only exit the current iteration of the loop, not the entire loop nor the function itself. The loop will continue to the next iteration.
So how could we solve the problem?
One approach could be using the for..of loop instead of ForEach.
So let's modify the above code as follows.

function containsDuplicate(nums) {
  const dups = [];
  for (const num of nums) {
    if (dups.includes(num)) {
      return true; // Found a duplicate
    }
    dups.push(num);
  }
  return false; // No duplicates found
}
const nums = [1, 2, 3, 3, 5];
console.log(containsDuplicate(nums));
Enter fullscreen mode Exit fullscreen mode

Now it behaves as expected. That is because, in the for...of loop (which is not a higher-order function), the return statement will exit the loop and the function (or block scope) in which it is used.

Conclusion: Beware of the temptation to use the return statement for early-exiting in the context of higher-order functions.

If you found this post helpful, please like and share. Your comments and discussions are warmly welcomed.
Always love learning from my peers and receiving the gift of feedback.

Happy coding!

Top comments (0)