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