Javascript - forEach vs map method in Arrays
Tags: javascript, beginners, webdev, node
Published: 2021-04-01 18:20:55

Javascript provides us with different functions to make our development life easy but if you have worked with Javascript for a little while, you understand how weird bugs can pop up if we don't understand the complete need of a function. Arrays in javascript provide two different functions to iterate through an array, `Array.prototype.forEach` and `Array.prototype.map`

## Definition
`map` takes one mandatory parameter as an argument which is a function (callback function) that defines what is required to be done to the element. It expects a value to be returned in the callback function and the map() returns a `new array` with the specified modifications on each value of the original value.

```
const arr = [1,2,3]
let result = arr.map(val=>{
    return val*2
})
console.log(result) // [2,4,6]
```

`forEach` also takes one mandatory parameter which is the callback function that defines what needs to done to the element. Although it does not expect any value to be returned and the complete .forEach() function returns `undefined`.

```
const arr = [1,2,3]
let result = arr.forEach(val=>{
    console.log(val*2) // 2 4 6
})
console.log(result) // undefined
```

## Differences

### 1. Return Value
The main difference between `map` and `forEach` is that `map` returns a new array whereas `forEach` returns undefined.

### 2. Mutability 
MDN Docs of [forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) and [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) say the following for both of these.

> `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 (although callback, if invoked, may do so).

What this basically means is that both of them do not change the original array but the logic inside the callback function may do so.

### 3. Performance
Performance is arguably one of the most important part of the codebase and hence it makes sense to cover the performance of these two functions.

Although since both these functions have different usecases, there is no universal way to compare both of them equally. I have used the performance APi to cover the performance of both of these functions.

```
let arr = [2,3,5,6,8,0]

let startTime = performance.now()
arr.forEach(num=>num*2)
let endTime = performance.now()
console.log("TIme taken by forEach is " + (endTime - startTime) +" milliseconds")
```
```
let arr = [2,3,5,6,8,0]

let startTime = performance.now()
arr.map(num=>num*2)
let endTime = performance.now()
console.log("TIme taken by map is" + (endTime - startTime) +" milliseconds")
```
My observations were that map was faster when array size was small but as array size started crossing 10^5, forEach showed better performance. 
But feel free to comment down your observations for the same as well.

Bonus - Another thing I noticed is that the use of for loop gave better performance in all cases but it affects the readability of code.

## When to use map and forEach

So, we dived deep into how the functions are working and saw how we use them in different cases but how do you figure out which one to use in what situations.

As a rule of thumb, we want to use forEach in cases when we do not want to store the result of the modifications and only want to access the values and perform operations using the value.

So we should use map when we require the resultant array, another advantage of using map is the ability of function chaining. 

```
const arr = [1,2,3,4,5];
const result  = arr.map(x=>x*2).filter(x=>x>=5)
```
Here the filter function is chained to the map function as it returns an array. This provides easily readable code and keeps the codebase clean.

## Conclusion

- Both `forEach` and `map` are powerful functions with different use cases but can be used to do almost everything that the other one does.
- Using a for loop gives better performance than both the inbuilt functions.
- map returns the resultant array whereas forEach returns undefined.