JavaScript: differentiating between for (), forEach(), and map()
While going through the freeCodeCamp curriculum I was introduced to multiple methods of iterating over arrays, and three of them - for (), forEach(), and map() - seemed exactly the same. I couldn't understand why I needed so many ways to iterate over an array, but I wasn't dense enough to assume there weren't good reasons for each method. I found that, while any task accomplished using one method can be accomplished with the others, each method provides advantages the others do not.
for (): The for statement is the basic way to create a loop to iterate over an array. A for loop generally contains an initialization, condition, and final expression. For example, say we have an array savingsAccounts
, and each element in the array represents one of our savings accounts. If we wanted to iterate over the entire array and print each element to the console, we could use a for loop like this:
var savingsAccounts = [1500, 2000, 2500, 3000];
for (var i = 0; i < savingsAccounts.length; i++) {
console.log(savingsAccounts[i]);
}
//1500
//2000
//2500
//3000
The for loop is very flexible and often the most performant option, but it lacks in the areas of readability and ease of implementation. The above example is fairly simple, but for loops can get messy quickly and are not nearly as recognizable as using some of the methods readily available to us in JavaScript.
forEach(): The forEach() method can perform the same operation as the for loop above but in a much cleaner and more recognizable way. forEach() will execute the provided callback function on each element in the array much like the for loop executes whatever instructions it is given on each element until the given condition is met.
var savingsAccounts = [1500, 2000, 2500, 3000];
savingsAccounts.forEach(function(element) {
console.log(element);
});
//1500
//2000
//2500
//3000
Despite the simple example, we can already see that forEach() is more readable, the intent more recognizable, and we can do away with the extra variable we declared in the for loop. When you see forEach() you automatically know that you are iterating over the entire array and executing the callback function on each element. This differs from for () in that a for loop does not always iterate over each element in an array if the condition has already been met. Keep in mind that you cannot use "break" to stop a forEach() loop prematurely, so if you might want to stop the iteration early, a for loop is the better option. Lastly, if you are using Javascript as a functional language you will want to be careful with your usage of forEach() because it relies on side effects, which are generally to be avoided in functional programming.
Aside: chances are if you are reading this post you are like me and still exploring how functional programming is different from object-oriented, procedural, imperative etc. so this last comment about side effects might not mean a lot to you, but it is good to keep in mind as you continue to study and deepen your understanding! What are side effects? In the words of Eric Elliott, "a side effect is any application state change that is observable outside the called function other than its return value." forEach() returns "undefined", so anything accomplished via forEach() is achieved via side effects. For more on this and functional programming see Eric Elliott's Medium post - What is Functional Programming?. In addition, I highly recommend following Eric Elliott on Medium/Twitter. The man knows and loves his JavaScript and is a fantastic writer.
map(): The map() method operates much like forEach() in that it executes a callback function on each element of an array, but where forEach() simply returns "undefined", map() will return a new array with the results, leaving the original array unaltered. For example, if we wanted to take our savingsAccounts
array and find the future value of each based on a 6% rate of return we could do the following:
var savingsAccounts = [1500, 2000, 2500, 3000];
var rateOfReturn = 0.06;
var numPeriods = 10;
var futureValues = savingsAccounts.map(function(element) {
return Math.round(element * (1 + rateOfReturn)**numPeriods);
});
console.log(futureValues);
//[2686, 3582, 4477, 5373]
We could accomplish the same task using a for loop or forEach() in conjunction with push() to add each value to a new array, but map() makes it much simpler. In terms of readability, map() immediately lets us know that we are iterating over each element of the array, and returning a new array from the results of the callback function. Keep in mind that you could make changes via side effects using map() just like you can with forEach() but that is not its intended purpose.
There are tons of helpful methods available to us in JavaScript (check out filter() and reduce() for more helpful methods that iterate over arrays) and this post only scratched the surface. I would encourage anyone getting into JavaScript to dive into the documentation on each method to supplement your learning (links provided below), and to any readers more advanced than me, I would love to hear your thoughts and insights!
reference: MDN forEach(), MDN map(), MDN for statement, MDN Loops and Iteration, MDN filter(), MDN reduce(), What is Functional Programming? by Eric Elliott