Should You Stop Using .forEach() in Your JavaScript Code?

Coming from a PHP background, when I first saw people utilizing .forEach() method to walk through their arrays, my nooby self thought nothing of it — it’s the same exact implementation of a standard for loop, I told myself. After writing some JavaScript code, I quickly realized that the two had their differences.

In this article, I want to outline the differences behind the standard for loop and .forEach() method as well as comment on some of the benefits that each brings to the table.
Image source: Author

As a disclaimer, please don’t take the title literally. My goal with the article is to inform the reader of bottlenecks and provide insight as to when you may or may not want to use .forEach() — nothing more. Let’s get started!

How forEach works

The forEach method accepts a callback function as input and for each element in the array you are iterating over, this callback function will be executed. It should be noted that there are a few optional arguments that your callback function can accept. They include the current value that is passed to your function, the current value’s respective index. The forEach function also provides an optional argument for defining this within your callback function.

Consider the following:


The respective output would be:corgis - 0
are - 1
cool - 2


Short-Circuiting

If you are not aware of what short-circuiting is, it refers to when we early-terminate and/or skip an iteration of a loop. When we are using forEach(), there’s no way to leverage short-circuiting, which in all cases of our loop, we will endure a linear runtime with respect to the size of our array.

Why should I care about this? Imagine we have an unsorted array of 1 billion elements and we want to find a certain element. Let’s say we got really lucky and found this element in the first iteration of our loop. Realistically, we would want to early-return since we found what we were looking for, but the way forEach() is implemented, we will always run through the remaining elements. We would likely use the .findIndex() method for this type of problem.

Performance

In the forEach() method, since we are calling a callback function at every iteration, we are creating an additional scope overhead that leads to slower speeds compared to the native for loop. When compared to the traditional for loop, we have an initializing statement, a conditional that is evaluated at every iteration, and an execute stage after the body of the loop is incremented. Relative to the forEach() method, where we have to create additional function calls at each iteration, it is a lower cost.

To test the performance, I created a timer script that tracked the execution time after initializing an array. Both loops were executing a simple O(1) operation in their body:

Readability

When developing software, creating maintainable and readable code should be a top priority. I believe a very valid argument to continue using forEach() in your code is for the sake of readability. With method chaining becoming almost second nature for arrays in JavaScript, it just reads better to run through an array using a forEach() loop instead of a for loop.

It should also be noted that cases where your input size is extremely large, as in the example above, tend to be unlikely. At a reasonable input size, the two loops are performing relatively the same. Would you rather have a function that is performing a few milliseconds faster at the expense of readability?

Conclusion

The methods that have been released with the last versions of ECMAScript have raised the bar for JavaScript as a whole. I am a prime believer in using the right tool for the job. If you need to read through a huge number of elements in an array, then maybe a native for loop might be the solution to your problem. Otherwise, I see no issue outside of slight performance loss when using .forEach() or any of the later released ES array methods. The tradeoff between readability and performance is one I would favor in most situations.


WRITTEN BY
Post a Comment