Javascript methods: forEach vs map

Tell us what’s happening:

I’m here to understand the difference between map and forEach.

Suppose I have an array of fruits:

fruits = [ {
    name: 'banana',
    color: 'yellow'
}, {
    name: 'apple',
    color: 'red'
}];

let newArray = fruits.map(fruit => {
   fruit.price = '€ 1.99';
});

console.log(fruits); 
console.log(newArray);

As far as I know map method doesn’t change the original array.
Why console.log(fruits) doesn’t return the original array?

[
  { name: 'banana', color: 'yellow', price: '€ 1.99' },
  { name: 'apple', color: 'red', price: '€ 1.99' }
]

Why console.log(newArray) returns the following?

[ undefined, undefined ]

Can someone help me with this?
Thanks a lot

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36.

map does not mutate the array on which it is called (although callback, if invoked, may do so). mdn

you don’t return anything from callback , thats why you see [undefined, undefined]

1 Like

Hi Annestezia,
thanks so much for your quick reply.
If I add a return statement inside the callback function I still don’t understand why I’ll have:

[
{ name: ‘banana’, color: ‘yellow’, price: ‘€ 1.99’ },
{ name: ‘apple’, color: ‘red’, price: ‘€ 1.99’ }
]

instead of:

[
{name: ‘banana’, color: ‘yellow’},
{ name: ‘apple’, color: ‘red’}
];


Furthermore, I don’t see any difference if I use forEach or map method :frowning:

Hey @Damiano,

  • Next time you want to showcase a code, use the ` backtick so it is easier for everyone to read. See this post to find the backtick on your keyboard. The “preformatted text” tool in the editor (</>) will also add backticks around text.

Yes sure, I’ll do it

Hey @Damiano,

forEach() is just a for loop wrapped in the function, nothing more. And the same way for loop doesn’t produce any value, forEach method doesn’t return anything. In contrast map method produces value.

Now let’s make an analogy. You’re a postman! You have an array of addresses:

  • You will use forEach when you need to go to each address and drop the letter or package - no return value. In programming we call this side-effect.

  • You will use map if you need to take this list and ask how many people live in the each address. And you will do that by copying initial list and adding a column to it (without mutating original). And you will bring back some value. Alright?

Hope that would be enough to understand the difference.

1 Like

You have already received awesome answers, so I will just focus on explaining this part.

this goes in a different direction that you may expect
this happens for the same reason that this happen:

let a = [1, 2, 3];
// let's make a copy of a
let b = a;
// now let's change a
a[1] = 0;
// and let's try to logs b to be sure it is still the same
console.log(b) //this logs [1, 0, 3]

b is not the same.

Arrays and objects are passed by reference, so when you just do let b = a now both variables reference the same array.

the map method pass each element to the callback function, in this case as they are objects, a reference to the object is passed to the callback, you can do fruit.price = '€ 1.99' to change the object.

You are also not using map correctly, as map needs to return the new value of the array element. Your callback function doesn’t return anything.

So the function should be something like fruit => ({...fruit, price: '€ 1.99'}) so you return an object that includes the price, and the new array will have that object inside.
This callback function changes nothing, just returns a new value.

1 Like

Thanks so much for your replies. These concepts are a bit weird to me at the moment but I hope I’ll understand them better soon :slight_smile: