Source: medium.com/better-prog… Translated by Moon: Front-end Full Stack Developer

Some of the most popular features in JavaScript are probably Map and forEach. They have existed since ECMAScript 5 (ES5 for short).

In this article, I’ll discuss the main differences between them and show you some examples of their use.

Before reading

Basically, iterating through an object in JavaScript depends on whether the object is iterable. By default, arrays are iterable. Map and forEach are included in Array.prototype, so we don’t have to worry about iterability. If you want to learn more, I recommend you take a look at what an iterable is in JavaScript!

What are map() and forEach()?

Map and forEach are helper methods in arrays that can easily loop over arrays. We used to loop through an array like this, without any helper functions.

var array = ['1'.'2'.'3'];
for (var i = 0; i < array.length; i += 1) {
  console.log(Number(array[i]));
}
/ / 1
/ / 2
/ / 3
Copy the code

The for loop has existed since the beginning of the JavaScript era. It contains three expressions: an initial value, a condition, and a final expression.

This is the classic method of looping arrays. Starting with ECMAScript 5, new features seem to make us happier.

map

The map does exactly the same thing as the for loop, except that the map creates a new array, which results in the provided function being called on each element in the calling array.

It takes two arguments: a callback function to be called later when map or forEach is called, and a context variable called thisArg to be used when the callback function is called.

const arr = ['1'.'2'.'3'];
// The callback function takes three arguments
// Take the current value of the array as the first argument
// The position of the current value in the array as the second argument
// Take the original source array as the third argument
const cb = (str, i, origin) = > {
  console.log(`${i}: The ${Number(str)} / ${origin}`);
};
arr.map(cb);
// 0: 1/1,2,3
// 1: 2/1,2,3
// 2/3/1,2,3
Copy the code

The callback function can be used as follows.

arr.map((str) = > { console.log(Number(str)); })
Copy the code

The result of the map is not equal to the original array.

const arr = [1];
const new_arr = arr.map(d= > d);

arr === new_arr; // false
Copy the code

You can also pass the object to the map as thisArg.

const obj = { name: 'Jane' };

[1].map(function() {
  // { name: 'Jane' }
  console.dir(this);
}, obj);

[1].map(() = > {
  // window
  console.dir(this);
}, obj);
Copy the code

ThisArg object obj becomes map. But the arrow callback cannot take obj as its thisArg.

This is because arrow functions are different from normal functions.

forEach

ForEach is another looping function for arrays, but map and forEach are used differently. Map and forEach can take two arguments — the callback function and thisArg, which are used for their this.

const arr = ['1'.'2'.'3'];
// The callback function takes three arguments
// Take the current value of the array as the first argument
// The position of the current value in the array as the second argument
// Take the original source array as the third argument
const cb = (str, i, origin) = > {
  console.log(`${i}: The ${Number(str)} / ${origin}`);
};
arr.forEach(cb);
// 0: 1/1,2,3
// 1: 2/1,2,3
// 2/3/1,2,3
Copy the code

What’s the difference?

Map returns a new array of its original array, but forEach does not. But they both ensure the immutability of the original object.

[1.2.3].map(d= > d + 1); / / [2, 3, 4];
[1.2.3].forEach(d= > d + 1); // undefined;
Copy the code

ForEach cannot guarantee the immutability of an array if you change the value within it. This method only guarantees invariance if you don’t touch any of the values in it.

[{a: 1.b: 2}, {a: 10.b: 20}].forEach((obj) = > obj.a += 1);
// [{a: 2, b: 2}, {a: 11, b: 21}]
// Array changed!
Copy the code

When to use map() and forEach()?

Since the main difference between them is whether or not there is a return value, you would want to use map to make a new array, whereas you would want to use forEach just to map to an array.

This is a simple example.

const people = [
  { name: 'Josh'.whatCanDo: 'painting' },
  { name: 'Lay'.whatCanDo: 'security' },
  { name: 'Ralph'.whatCanDo: 'cleaning'}];function makeWorkers(people) {
  return people.map((person) = > {
    const { name, whatCanDo } = person;
    return <li key={name}>My name is {name}, I can do {whatCanDo}</li>
  });
}

<ul>makeWorkers(people)</ul>
Copy the code

For example, in React, a map is a very common method for creating elements, because a map creates and returns a new array after performing operations on the original array.

const mySubjectId = ['154'.'773'.'245'];

function countSubjects(subjects) {
  let cnt = 0;
  
  subjects.forEach(subject= > {
    if (mySubjectId.includes(subject.id)) {
      cnt += 1; }});return cnt;
}

countSubjects([
  { id: '223'.teacher: 'Mark' },
  { id: '154'.teacher: 'Linda'}]);/ / 1
Copy the code

On the other hand, forEach is useful when you want to do something with the data without creating a new array. By the way, you can refactor the example using filter.

subjects.filter(subject= > mySubjectId.includes(subject.id)).length;
Copy the code

To sum up, I recommend that you use map when creating a new array, and forEach when you don’t need to make a new array but do something with the data.

Speed is

Some posts mentioned that Map is faster than forEach. So, I wonder if it’s true. I found this comparison.

The code looks very similar, but the result is the opposite. Some tests say forEach is faster, others say Map is faster. Maybe you’re telling yourself that Map /forEach is faster than the others, and you’re probably right. To be honest, I’m not sure. I think readability is much more important in modern Web development than speed between map and forEach.

But one thing’s for sure — both are slower than JavaScript’s built-in for loop.