JavaScript 有一些方便的方法可以帮助我们遍历数组。最常用于迭代的两个是 Array.prototype.map()
和 Array.prototype.forEach()
。
但我认为它们仍然有点不清楚,特别是对于初学者来说。因为它们都进行了迭代并输出了一些东西。那么区别是什么呢?
在本文中,我们将研究以下内容:
- 定义
- 返回值
- 是否能够链接其他方法
- 可变性
- 性能速度
- 小结
定义
map
方法接收一个函数作为参数。然后它将参数应用于每个元素并返回一个全新的数组,其中填充了调用提供的函数的结果。
这意味着它返回一个新数组,其中包含数组每个元素的执行结果。它将始终返回相同数量的项目。
与 map
一样,forEach()
方法接收一个函数作为参数,并对每个数组元素执行一次。但是,它不会返回像 map
这样的新数组,而是返回 undefined
。
返回值
map()
和 forEach()
之间的第一个区别是返回值。forEach()
方法返回 undefined
,而 map()
返回一个包含转换后元素的新数组。即使它们做同样的工作,返回值却不同。
是否能够链接其他方法
这些数组方法之间的第二个区别是 map()
是可链接的。这意味着你可以在对数组执行 map()
方法后附加 reduce()
、sort()
、filter()
等。
这是你不能用 forEach()
做的事情,因为你可能猜到,它返回 undefined
。
可变性
一般来说,“mutate” 这个词意味着改变、交替、修改或变换。在 JavaScript 世界中,它具有相同的含义。
可变对象是在创建后可以修改其状态的对象。那么,forEach
和 map
的可变性呢?
根据 MDN 文档:
forEach()
不会改变调用它的数组。(但是,callback
可能会这样做)。
map()
不会改变调用它的数组(尽管 callback
可能会这样做)。
JavaScript 很奇怪。
在这里,我们看到了一个非常相似的定义,我们都知道它们都接收 callback
作为参数。那么,哪一个依赖于不变性?
在我看来,这个定义并不清楚。要知道哪个不会改变原始数组,我们首先要检查这两种方法是如何工作的。
map()
方法返回一个全新的数组,其中包含转换后的元素和相同数量的数据。对于 forEach()
的情况下,即使它返回 undefined
,它也会用 callback
改变原始数组。
因此,我们清楚地看到 map()
依赖于不变性,而 forEach()
是一个 mutator 方法。
注意❗
如果数组是引用类型,map是可以改变原数组的。
性能速度
关于性能速度,它们有点不同。但是,有关系吗?嗯,这取决于各种因素,例如你的计算机、你正在处理的数据量等等。
你可以使用下面的示例或使用 jsPerf 自行检查,看看哪个更快。
小结
map()
和 forEach()
之间的选择将取决于你的用例。如果你计划更改、替换或使用数据,那么你应该选择 map()
,因为它会返回一个包含转换后数据的新数组。
但是,如果你不需要返回的数组,请不要使用 map()
- 而是使用 forEach()
甚至 for
循环。