I recently wrote a post here at Crooked Code discussing that, as a relative beginner to JavaScript, I’ve had a tendency to use loops exclusively when traversing an array.
Further, I wondered if it would be better if I were taking advantage of the methods built into the array prototype. Methods such as forEach(), reduce(), map() and filter().
Let’s take a look…
For reference, MDN is a great resource to learn more about arrays and the array prototype. They cover forEach() in far greater detail than I will here, so I encourage you to go read it.
How do you use forEach()?
Simply put, forEach() takes a callback function as an argument and executes that function on each element of the calling array.
The callback function takes 3 arguments – the element value, the element index and the array being traversed. Instances where the index and array are not needed in the callback function, you’ll see it invoked with only the element value.
A simple example of forEach():
1 2 3 4 5 6 7 8 9 10 |
var array = ['one', 'two', 'three', 'four']; array.forEach(function(val){ console.log(val); }); //one //two //three //four |
When should I use forEach vs. a for loop?
Researching the differences between a for loop and forEach() to write this post has been somewhat enlightening (there are some very opinionated people out there).
First, if you need to stop or break out of the loop before every element is visited, forEach() is not the right function. In such cases, use a for loop, or look into using every() or some().
Other than that, it seems to come down to performance vs. readability.
Improved Readability with forEach()
Let’s revisit the example above and compare the same functionality using a for loop.
1 2 3 4 5 6 7 8 9 10 11 |
var array = ['one', 'two', 'three', 'four']; //log array using forEach() array.forEach(function(val){ console.log(val); }); //log array using for loop for(let i=0; i<array.length; i++){ console.log(array[i]); }; |
I’ll let you be the judge as to which one is more readable…
Personally, I think the more you use forEach(), the more you’ll prefer it to a for loop for readability. Clearly, not using additional variables or worrying about ‘off by one errors’ is an added benefit too.
It’s also worth mentioning that ES6 syntax, with the arrow function, improves the readability even further. I’m still writing my functions the archaic way, which is what I did above, but the same function written in ES6 would look something like this:
1 2 |
//log array using forEach() array.forEach((val)=>{console.log(val);}); |
Performance
I used jsperf to run performance tests to compare for loops, while loops and forEach(). The tests were run in the Chrome browser.
The for and while loops were the clear winners (6,233 and 6,261 Ops/sec respectively). forEach() was 18% slower at 5,202 Ops/sec.
So, on a sheer performance basis, the loops were faster than the function call to forEach(). I was a little surprised, however, that forEach() was only 18% slower than the loops.
Bottom Line…
I think you could argue either way of which one, the for loop or forEach(), is better. Ultimately, I think it depends on the use case…
If you’re developing something that is very data intensive, and the extra performance of the for loop will make a difference, go with the for loop.
Otherwise, if you find forEach() to be more readable and aren’t iterating over huge data sets, use forEach()…
Either way, get out there and build something cool… That’s it for now, see you next time.
-Jeremy
Side Note
Finally, I need to mention that the forEach() method takes an optional second argument that provides the value to use as this when executing the callback.
Covering this in depth was beyond the scope of this blog post, but You Don’t Know JavaScript: this & Object Prototypes Ch. 2 has an excellent, easy to understand example of using the this argument.