loading...

.map() vs .forEach()

torianne02 profile image Victoria Fluharty ・3 min read

I am creating this quick explanation of the differences between using .map() and .forEach(), because I originally had a difficult time understanding the fundamental reasons why you would want to use one over the other. I thought that you could use them interchangeably and it wouldn’t be a huge deal, but I was wrong.

I personally know that while learning a new language, it is always these small details that really throw you for a loop, so I want to make this explanation as quick and simple as possible, so that it is easy to understand!

Let’s get started.

.forEach()

.forEach() is an array iterator that executes a function (provided by you, the dev) once per each element within a given array. This means that we, as devs, get to provide a function that we want to be used on each element of the array. Let’s say that we have an array of dogs and we want each dog to get a treat. We can do this by executing the following code:

var dogs = [Spot, Buddy, Princess]

dogs.forEach(function(dog) {
  console.log(dog +  has eaten the treat!)
});

// “Spot has eaten the treat!”
// “Buddy has eaten the treat!”
// “Princess has eaten the treat!”

console.log(dogs) // [“Spot”, “Buddy”, “Princess”]

As you can see, we had each element of the array plus the statement “has eaten the treat!” printed to the console. I must note at this time that while it does print these statements to the console, what is being executed in the function is not saved anywhere. The original array is not being manipulated, nor is a new array being created. Which is why when I call dogs, it returns the original array completely unharmed!

If you wanted to save the results of the function, then you would need to do so manually. I can save all of these statements by simply creating a new array and pushing to this new array within the function, like so:

var dogs = [Spot, Buddy, Princess]
var result = []

dogs.forEach(function(dog) {
  result.push(dog +  has eaten the treat!)
});

console.log(result) // [“Spot has eaten the treat!”, “Buddy has eaten the treat!”, “Princess has eaten the treat!”]

.map()

.map() is similar to .forEach() because they are both array iterators that execute a provided function on every element within the given array. Now the big difference between the two, is that with .map() we don’t need to tell our function to add every element to a new array like we do with .forEach(). With .map() it creates a new array out of the results of the given function without harming the original array. In other words, .map() allows us to transform the elements within an array, but in order to save this result we still need to set the .map() statement to a new variable. Let’s take our dogs example again and we will make each dog play fetch.

var dogs = [Spot, Buddy, Princess]

var result = dogs.map(dog => dog +  has fetched the ball!);

console.log(result)  // [“Spot has fetched the ball!”, “Buddy has fetched the ball!”, “Princess has fetched the ball!”]
console.log(dogs) // [“Spot”, “Buddy”, “Princess”]

Notice how result is now an array of strings and dogs remains in its original condition.

Final Thoughts

If you want to iterate over an array without needing the results of the function to be saved, then I suggest using .forEach(). Opposite of this, if you need the results of the function in order to execute other code that depends on it, use .map().

Sources

Array.prototype.map()
Array.prototype.forEach()
Why and when to use forEach, map, filter, reduce, and find in JavaScript

Posted on Mar 30 '19 by:

torianne02 profile

Victoria Fluharty

@torianne02

["Software Engineer @ FireHydrant", "Cat Mom", "Ruby Enthusiast", "Forever Learner"]

Discussion

markdown guide
 

Another thing I point out to devs new to javascript is the callback passed to forEach is necessarily an impure function since it doesn't return anything.

If a dev sees it in code they should assume it is mutating state.

Whereas, although map can be abused to mutate state, since it always returns a new array, its design implies its callback is a pure function.

map and filter are best treated as using pure functions.

Because forEach doesn't work how the above two array methods work, I tend to avoid using it altogether and instead use the modern for ... of iteration approach when I need to mutate state.

Thanks for writing this comparison. I've seen many devs get confused about this stuff 👍

 

Implies is a strong word... I'd say, "allows for". Per the ECMA standard, map() guarantees invocation order against the elements of the array, something that would be unnecessary to specify in a function that implies a pure function callback.

The standard itself explicitly says that while map doesn't mutate the object on which it is called, the callback function may mutate it (not just any old side effect here like console.log(), but a mutation of the object being called)... and there's an odd rule that if you delete an element from the array during the invocation of map(), but before map visits that element, that element will not be visited.

Sure, it's better style if it is pure, but the implication, if anything, is that it may be impure.

 

Those are good points.

In much of the code I see, map and filter are used with pure functions.

So, despite what the language allows, the use of them implies pure functions in my experience.

Following this pattern means you don't have to worry about the scenario you describe.

 

I wish that you have written this post just a week earlier. My life would be so much easier. Amazing post!

 

I'm sorry I wasn't there in time to save you! haha.

 

thank you very much, Victoria, for your extremely clear explanation. I would say that a functional programming style is ever a good choice, so I vote "map" for President! Have a good week end :)

 

You're welcome and thank you for commenting and adding some lovely humor. haha! I hope you also have a great weekend.

 

Thank you so much for explaining it this way. I've sort of always understood the difference but now it makes a lot more sense.

 

Also in java forEach is a terminal operation that closes the stream when it finishes. In the other hand, the map as in js it returns a new stream with the result of the mapping.

 

I think I will tweet this post a few more times.

 

If I was a JS newbie I would have needed this

 
 

Oh wow thank you! I've always completely ignored learning map in any language because I had foreach but this is a great straight forward explanation
Time to look over my old code 😁

 
var dogs = [“Spot”, “Buddy”, “Princess”]
var result = []

dogs.forEach(function(dog) {
  result.push(dog + “ has eaten the treat!”)
});

console.log(result)

You forgot to mention, that forEach mutates an original array, so your push is redundant here:

const dogs = [“Spot”, “Buddy”, “Princess”]

dogs.forEach(dog => `${dog} has eaten the treat!`);

console.log(dogs)

If you want to create another array, then you should use map().
Don't misinform people.

 

First off, Alexander, thank you for taking the time to comment on my post. I always appreciate when people take the time to engage with others here on DEV.

Secondly, unfortunately, you are incorrect in regards to mutation. .forEach does not mutate the array it is called on and has a return value of undefined. Here is a link to the documentation for you to read.

With the code you are addressing, the purpose was not to mutate the original array, dogs, but to save the output of the function being passed into the iterator to the new result array.

You can see in the screenshot of a Repl.it I created to test the code below, that my code does NOT mutate the original array.

screenshot of my above code ran on repl.it

Now you'll notice in a screenshot using your code, that it ALSO DOES NOT mutate the dogs array.

screenshot of Alexander's code on repl.it

The point of this article was to discuss two different types of array iterators. If you read the entire article from start to finish you would have hopefully noticed the Final Thoughts section which states

If you want to iterate over an array without needing the results of the function to be saved, then I suggest using .forEach(). Opposite of this, if you need the results of the function in order to execute other code that depends on it, use .map().

With this, I am saying that if you ever need the results of what you are receiving from the array iterator, then .forEach isn't what you want to use since it requires more code. .map is what you'd want to use instead.

Now, please in the future, when you comment on someone's post here on DEV, please don't use passive-aggressive phrases like "Don't misinform people." You should politely correct it.

 

Great article! There is another great one I just read talking about the differences in React as well theforge.ca/react-for-loop-arrays-... and how you shouldn't be using forEach to display data in react, since it's not the best For Loop for it.