JavaScript has some methods that help us to iterate through Arrays. The two most used are foreach()
and map()
in Javascript. But I believe there is a lot of doubt between these two methods.
Because they both do some iteration. So, what’s the difference?
We will define each method, and where each one fits in, to try to understand better what we can do with each one:
The
map()
method gets a function as a parameter. This function is invoked for each Array element and, at the end, the method returns a completely new array filled with the results of the given function call.
const numbers = [5, 4, 3, 2, 1]
console.log(numbers.map(element => element * element)) //[ 25, 16, 9, 4, 1 ]
This means that it returns a new array that contains an image of each array element. It will always return the same number of items.
The
forEach()
method receives a function as an argument and executes it once for each Array element. However, instead of returning a new array as themap()
method, it returnsundefined
.
const numbers = [5, 4, 3, 2, 1]
console.log(numbers.forEach(element => element * element)) //undefined
As you can already see, one of the main differences between forEach
and map
in Javascript is the return of each method.
The forEach()
method returns undefined
, while map()
returns a new array with the transformed elements.
let numbers = [5, 4, 3, 2, 1]
console.log(numbers.map(element => element * element)) //[ 25, 16, 9, 4, 1 ]
console.log(numbers.forEach(element => element * element)) //undefined
The second difference between these methods is the fact that map()
is chainable. This means that you can chain other methods (like reduce()
, sort()
, filter()
, and so on), after executing the map()
method in an array.
This is something you can’t do with forEach()
because, as you can guess, it returns undefined
.
let numbers = [5, 4, 3, 2, 1]
const newArrayMap = numbers.map(element => element * element).filter(x => x > 9);
console.log(newArrayMap); //[ 25, 16 ]
const newArrayForEach = numbers.forEach(element => element * element).filter(x => x > 9);
console.log(newArrayForEach) // Cannot read property 'filter' of undefined
Mutability means ” Capacity or ability to change.”
A mutable object is an object whose state can be changed after its creation. Regarding mutability, how do the foreach()
and map()
methods in Javascript behave?
Well, according to the MDN documentation:
forEach()
does not modify the array in which it is called. (However, the callback method can do this).
map()
does not modify the array in which it is called (although the callback method, if invoked, can do that).
That’s perhaps the most confusing explanation I’ve read in recent months. Let’s clear things up.
When the map()
method is called, it returns a completely new Array and does not change the original Array to which it was called. And all the transformation happens in this new Array, that at the beginning it’s a “copy” of the original Array.
The forEach()
method does not return anything (undefined
). It simply calls a function provided in each element of its array. This call back has permission to change the Array that was called. It means that forEach()
does not create a copy of the original Array to interact over it. But also does not return anything, that’s why you don’t see any difference in the original Array.
Notice in the example below that the map()
method makes the necessary changes and returns a new Array. To simulate the same effect using forEach()
I needed to change the original value.
let numbers = [5, 4, 3, 2, 1]
const newArrayMap = numbers.map(element => element * element);
console.log(newArrayMap); //[ 25, 16, 9, 4, 1 ]
console.log(numbers); //[ 5, 4, 3, 2, 1 ]
const newArrayForEach = numbers.forEach(
(element, index) =>
numbers[index] = element * element
);
console.log(numbers) // [ 25, 16, 9, 4, 1 ]
Although many sites state that the map()
method is up to 70% faster than the forEach()
method. This is not exactly what I found in my tests.
Actually, I found out the opposite. I tested several scenarios and in none of the tests did the forEach method perform less well. You can check one of the tests here. I believe that if the side effect of changing the original Array is not a problem, the forEach()
method fits very well with the proposal of being efficient.
Which is the best?
That depends on the result you want to get.forEach()
may be preferable when you’re not trying to change the data in your array, but instead want to just do something with it – like save it to a database or just display the data:
let names = ['Elon', 'Jeff', 'Mark'];
names.forEach((name) => {
console.log(name);
});
// Elon
// Jeff
// Mark
And the map()
method may be the best way to change the data because it returns a new Array with the data. And since the return is an Array we can take advantage of this to chain other methods like ( map()
, filter()
, reduce()
, etc.).
let arr = [1, 2, 3, 4, 5];
let arr2 = arr.map(num => num * 2).filter(num => num > 5);
// arr2 = [6, 8, 10
Check out the other Javascript tutorials, and sign up for our newsletter to receive news!
Leave a Reply