Originally posted on my blog
JavaScript has some handy methods which help us iterate our arrays. The two most used for iteration is Array.prototype.map()
and Array.prototype.forEach()
, however, they remain a little bit unclear, especially for a beginner. Because they both do an iteration and output something. So, what is the difference?
- Definition
- 1. The returning value
- 2. Ability to chain other methods
- 3. Mutability
- 4. Performance Speed
- Final Thoughts
Definition
The
map()
method creates a new array populated with the results of calling a provided function on every element in the calling array.The
forEach()
method executes a provided function once for each array element.
1. The returning value
The first difference between map()
and forEach()
is the returning value. The forEach()
method returns undefined
and map()
returns a new array with the transformed elements even if they do the same job, the returning value remains different.
const myAwesomeArray = [1, 2, 3, 4, 5]
myAwesomeArray.forEach(x => x * x)
//>>>>>>>>>>>>>return value: undefined
myAwesomeArray.map(x => x * x)
//>>>>>>>>>>>>>return value: [1, 4, 9, 16, 25]
2. Ability to chain other methods
The second difference between these array methods is the fact that map()
is chainable, that's mean, you can attach reduce()
, sort()
, filter()
etc. after performing a map()
method to an array. That's something you can't do with forEach()
because as you might guess it returns undefined
.
const myAwesomeArray = [1, 2, 3, 4, 5]
myAwesomeArray.forEach(x => x * x).reduce((total, value) => total + value)
//>>>>>>>>>>>>> Uncaught TypeError: Cannot read property 'reduce' of undefined
myAwesomeArray.map(x => x * x).reduce((total, value) => total + value)
//>>>>>>>>>>>>>return value: 55
3. Mutability
According to MDN documentation:
forEach()
does not mutate the array on which it is called. (However,callback
may do so).
map()
does not mutate the array on which it is called (althoughcallback
, if invoked, may do so).
JavaScript is weird.
Here, we see a very similar definition, and, we all know that they both receive a callback
as an argument, so, which one relies on immutability?
Well, in my opinion, this definition is not clear though. And to know which does not mutate the original array, we first have to check how these two methods work.
The map()
method returns an entirely new array with transformed elements and the same amount of data. In the case of forEach()
, even if it returns undefined
, it will mutate the original array with the callback
.
Therefore, we see clearly that map()
relies on immutability and forEach()
is a mutator method.
4. Performance Speed
Regarding performance speed, they are a little bit different. But, does it matter? Well, it depends on various things like the computer, the amount of data, etc. You can check it on your own with this example below or with jsPerf to see which is faster.
const myAwesomeArray = [1, 2, 3, 4, 5]
const startForEach = performance.now()
myAwesomeArray.forEach(x => (x + x) * 10000000000)
const endForEach = performance.now()
console.log(`Speed [forEach]: ${endForEach - startForEach} miliseconds`)
const startMap = performance.now()
myAwesomeArray.map(x => (x + x) * 10000000000)
const endMap = performance.now()
console.log(`Speed [map]: ${endMap - startMap} miliseconds`)
Final Thoughts
As always, the choice between map()
and forEach()
will depend on the use case. If you plan to change, alternate or use the data, it's preferable to pick map()
, because it returns a new array with the transformed data. But, if you won't need the returned array, don't use map()
, instead use forEach()
or even a for
loop.
Hopefully, this post makes clear the differences between these two methods. If there are more differences, please share them in the comment section, otherwise thanks for reading it.
Top comments (21)
I love this kind of small informative articles.
Glad you like it.
Liked the post. I think the easiest point for me to remember the difference is how I would use the two function names in a sentence. For a .map() example, "I'm going to this new land area out." This sentence implies the production of some item, a new map of a new land area. Just like the function .map(), we will have a new item mapped out after the action is done. For forEach(), "For each lemon I have, I'm going to cut it in half." Here for each implies that I'm going to perform an action on each individual lemon. Just like the function call itself.
For most function names I try to do some kind of relation to their context in a sentence.
After all, I bet there was probably a bit of though that was put into the naming of these functions by the JS architect who designed them.
😁😁
😂😂The way of differentiating thing is just funny. I should give it a try.
Did not read the article, but the title reminded me of code I found were people used map instead of foreach.
Which whenever it happens makes me want to headbut my screen in excited anger.
I’ll read the article now, but my bruised forehead wants to thank you in advance.
Thank you so much. Hopefully, you'll find value on it
Great article I have found mdn is great but sometimes you get those really vague explanations of things. MDN is also not the end all be all it's kind of like the wikipedia of Js css etc. I say that because it's editable by you and my right now. Sometimes there is validation of what you say is true when you are putting it in but not when I updated some css docs.
I totally agree. Sometimes, things become clear once you test it by yourself. But overall, MDN is great.
I would like to clarify that, regarding point 1,
map()
andforEach()
do not expect the same type of functions.forEach()
expects a function that takes in one argument and returns nothing. Passing in the functionx => x * x
wouldn't even be valid in many other languages with a similar function.map()
instead expects a function that takes in one argument and returns a new value of any type.Since
forEach()
is a void function (undefined in JS) it should preferably only be used for IO operations where no return value is expected (eg. changing the DOM or printing to console).Thanks, for your comment I intentionally use the same example for both
map
andforEach
to just not confuse folks. But, if you read my final thought, you'll see thatmap
is all about transforming data, and this example should be done withmap
.Thank you for the very handy article and the great explanation. I am just learning about both these methods for the first time, and while I assumed there was at least one difference (why else have two methods), the tutorial I am following and MDN unfortunately were both rather vague on the matter. So this was a great explanation that came at exactly the right time. Thanks for writing it.
Your comment means a lot to me. I'm glad you find value on it. And thanks again for reading it.
really nice post :) thank you for sharing
I'm glad you like it. Thanks again for reading it
Very nice post
Thanks, I'm glad you like it.
Knowing the difference between the two in terms of mutability and performance will certainly help. Thank you for writing this informative article.
You're welcome. Thanks for reading it too
Very handy information. Thank you for the article 👍
You're welcome