[译]在 JavaScript 中 为何你应当使用 map 和 filter 来替代 forEach

当你须要将一个数组或一部分数组复制到一个新数组时,首选 mapfilter,而不是 forEach前端

咨询工做对我来讲最大的好处之一是我能够看到无数的项目。这些项目有大有小,使用的编程语言和开发人员能力差别很大。尽管我认为有不少模式都应该放弃使用,但 JavaScript 语言中的这种模式尤为要弃用:使用 forEach 建立新数组。该模式实际上很是简单,看起来像这样:react

const kids = [];
people.forEach(person => {
  if (person.age < 15) {
    kids.push({ id: person.id, name: person.name });
  }
});
复制代码

这段代码的意思是,处理一个包含全部人的数组,以找出每一个年龄小于 15 岁的人。而后选择 person 对象中的其中几个字段做为 'kids' 对象,并将其复制到 kids 数组中。android

虽然这是有效的,但这是很是必要的(参见编程范例)编码方式。你可能有所怀疑,这有什么不对?要理解这一点,让咱们首先熟悉两个朋友 mapfilterios

mapfilter

在 2015 年,mapfilter 做为 ES6 特性集的一部分被引入 JavaScript。它们是数组的方法,容许在 JavaScript 中进行更多函数式编程。像在函数式编程世界中同样,这两种方法都没有改变原始数组。相反,它们都返回一个新数组。它们都接受函数类型的单个参数。而后在原始数组中的每一项上调用此函数以生成结果数组。让咱们看看这些方法的做用:git

  • map:每项调用函数处理后的值存放到返回的新数组中。
  • filter:每项调用函数处理后的值决定该项是否应该放在方法返回的新数组中。

在同一个团体中他们也有第三个朋友,但较少使用。这位朋友的名字是 reducegithub

如下是能够查看实际操做结果的简单示例:编程

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]
复制代码

既然咱们知道 mapfilter 会作什么,让咱们接下来看一个我但愿前面的示例应当如何编写的例子:后端

const kids = people
  .filter(person => person.age < 15)
  .map(person => ({ id: person.id, name: person.name }));
复制代码

若是您想知道 map 中使用的 lambda 的语法,请参阅此 Stack Overflow answer 以获取解释。数组

那么这个实现究竟有什么好处:promise

  • 关注点分离:过滤和更改数据格式是两个独立的问题,使用单独的方法能够分离关注点。
  • 可测试性:为实现这两个目的,一个简单的、纯函数的方法能够轻松地针对各类行为进行单元测试。值得注意的是,初始实现并不像它依赖于其范围 (kids 数组)以外的某些状态那样纯粹。
  • 可读性:因为这些方法具备过滤数据或更改数据格式的明确目的,所以很容易看出正在进行何种操做。特别是由于有那些同类功能的函数,如 reduce
  • 异步编程:forEachasync/await 不能很好地协同工做。另外一方面,map 提供了一个可以结合 promises 和 async/await 的有效模式。在下一篇博文中有关于此问题的更多信息。

另外一个值得注意的地方是,当你想引发反作用时(例如更改全局状态),不该当使用 map。特别是在不使用或存储 map 方法的返回值的状况下。

结论

mapfilter 的使用提供了许多好处,例如关注点分离、可测试性、可读性和对异步编程的支持。所以,对我来讲这是一个明智的选择。然而,我常常遇到使用 forEach 的开发人员。虽然函数式编程可能使人惧怕,这些方法有也具备来自该世界的某些特征,对它们并不用惧怕。在响应式编程中,mapfilter 也被大量使用,感谢 RxJS 的贡献,响应式编程如今愈来愈多地在 JavaScript 世界中使用。所以,下次你要写一个 forEach 时,首先要考虑其余方法。但要注意,它们可能会永久改变您的编码方式。

若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索