forEach
is that it primarily relies on side effects, whereas some native Array.prototype
alternatives make use of semantically-correct programming paradigms (such as reduction, mapping, and filtering) and may in turn introduce less incidental complexity (and enhance readability) when writing code.
3) You should be filtering
In this example, we have an array, and we want to eliminate items from an array that don’t meet a specific criteria. Here’s how you’ll see it done with forEach
:
Bad
[4, 5]
This is a typical implementation. With forEach
, you simply push each object to a completely new array. You’ll notice that this introduces extra state to maintain. More state equals more brainpower needed to understand what is happening.
Luckily, Array.prototype.filter
already has you covered there. It simply returns a new array of the items we want.
Good
[4, 5]
2) You should be mapping
In this example, we want to “change” each value in an array to something else. Here’s how we’d do it with forEach
:
Bad
["Josh Beam", "Ozzy Osbourne"]
Again, naked looping requires us to create additional state within our application.
Here, we’re gonna use map
instead. Again, it simply returns a new array without requiring us to do it ourselves:
Good
["Josh Beam", "Ozzy Osbourne"]
1) You should be reducing
Here, we want to combine certain values in an array.
Bad
15
In other words, when you think “reduce”, think about “collapsing” items into a new item. Another way to think of it is to imagine you have an array filled with the words of a sentence, and you want to concatenate them all into one string.
Good
15
Conclusion
You’ll notice one of the overarching concepts of all these three methods is that they all take the “functional route”, where they don’t necessarily require the manual creation of additional state. It is possible to introduce side effects within these methods, however, they don’t primarily rely on side effects to function. In other words, you’ll see that Array.prototype.forEach
primarly relies on side effects. It never returns a value other than undefined
unless you explicity force it to.
Why am I referring to functional programming in the context of JavaScript, which is clearly not a functional programming language? Well, to quote the omniscient Wikipedia article on functional programming:
Eliminating side effects, i.e. changes in state that do not depend on the function inputs, can make it much easier to understand and predict the behavior of a program
In other words, it can take more “brain power” to understand what is happening in a forEach
loop whose sole purpose is to mutate outside data based on side effects, whereas map
, reduce
, and filter
all have immediate and clear semantic meanings to the programmer (that’s not to say, though, that you can’t use the power of those methods for evil).