• Why you should replace forEach with map and filter in JavaScript
  • Roope Hakulinen
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: zhmhhu
  • Proofread by CoderMing, diliburong

When you need to copy an array or part of an array to a new array, map and filter are preferred over forEach.

One of the best things about consulting for me is that I get to see countless projects. These projects are large and small, and the programming languages used and the capabilities of the developers vary widely. While there are many patterns that I think should be discarded, this one in the JavaScript language in particular should be discarded: creating new arrays using forEach. The pattern is actually quite simple and looks something like this:

const kids = [];
people.forEach(person => {
  if(person.age < 15) { kids.push({ id: person.id, name: person.name }); }});Copy the code

What this code means is that it processes an array of all people to find each person under the age of 15. Then select a few of the fields in the Person object as ‘kids’ objects and copy them into the Kids array.

While this works, it is a very necessary (see programming example) way to code. You might be suspicious. What’s wrong with that? To understand this, let’s first familiarize ourselves with two friends, Map and Filter.

mapfilter

In 2015, Map and Filter were introduced to JavaScript as part of the ES6 feature set. They are array methods that allow for more functional programming in JavaScript. As in the functional programming world, neither approach changes the original array. Instead, they all return a new array. They both take a single parameter of a function type. This function is then called on each item in the original array to generate the result array. Let’s look at these methods in action:

  • map: The value processed by each calling function is stored in a new array returned.
  • filterThe value of each item processed by the calling function determines whether the item should be placed in the new array returned by the method.

They also have a third friend in the same group, but use it less frequently. The friend’s name is Reduce.

Here’s a simple example where you can see the result in action:

const numbers = [1, 2, 3, 4, 5]; const doubled = numbers.map(number => number * 2); // [2, 4, 6, 8, 10] const even = numbers.filter(number => number % 2 === 0); / / (2, 4]Copy the code

Now that we know what map and filter do, let’s look at an example of how I wish the previous example would have been written:

const kids = people
  .filter(person => person.age < 15)
  .map(person => ({ id: person.id, name: person.name }));
Copy the code

If you want to know the syntax for lambda used in map, see this Stack Overflow Answer for an explanation.

So what are the benefits of this implementation:

  • Separation of Concerns: Filtering and changing data formats are separate issues, and separate approaches can be used to separate concerns.
  • Testability: To achieve both purposes, a simple,Pure functionsCan be easily unit tested against a variety of behaviors. It is worth noting that the initial implementation is not as dependent on its scope as it is (kidsArray) as pure as some other state.
  • Readability: Because these methods have the explicit purpose of filtering data or changing data formats, it’s easy to see what’s going on. Especially because there are functions that have similar functions, such asreduce.
  • Asynchronous programming:forEachasync/awaitDoesn’t work well together. On the other hand,mapPromises offers a way to combine Promises andasync/awaitThe effective model of. More on this in the next blog post.

Another important point to note is that maps should not be used when you want to cause side effects, such as changing global state. Especially if you don’t use or store the return value of the Map method.

conclusion

The use of Map and filter provides many benefits, such as separation of concerns, testability, readability, and support for asynchronous programming. Therefore, it is a wise choice for me. However, I often encounter developers who use forEach. While functional programming can be intimidating, these methods have certain characteristics from the world that are not to be feared. Map and filter are also heavily used in reactive programming, which is now increasingly used in the JavaScript world thanks to the contributions of RxJS. So the next time you write a forEach, consider other methods first. But be aware that they can change the way you code forever.

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.