企业项目管理、ORK、研发管理与敏捷开发工具平台

网站首页 > 精选文章 正文

Javascript中,forEach和map到底有什么区别?

wudianyun 2024-12-23 10:13:48 精选文章 37 ℃

在平时做Code Review的时候,经常会看到这样的代码:

someArray.map( x => console.log(x) )

我都会要求修改成forEach,但经常会遇到有人反问:为什么要修改,map也没报错,没问题啊。

今天就想聊一下这个问题。

其实上面的这个代码,还是会有很多人认为应该修改成forEach的,但理由并不一定对。因为提到forEach和map的区别时,很多人会直接不假思索地说:

一个有返回值,一个没有返回值。

这个答案对吗?对,但完全没有触及本质。

真正的答案是:这两个方法其实毫无关系,各自用在各自不同的场景之下,只是看起来能够实现相似的功能而已。

forEach,其实就是for的一个语法糖:

const callback = f
const target = arr
for(let i = 0; i < target.length; i++) {
  f(target[i])
}

for代码块中,可以做任何事情,这只是一个按照顺序遍历的过程。

map来自于数学中的概念“函数”,也就是我们初中时候就学过的“一一映射”:把一个集合中的每一个值,按照某种变换过程,映射到另一个集合中。比如把所有的奇数加一,映射成所有的偶数。这个过程在语义上来说并不是“遍历”、“迭代”,而是所有值同时按照箭头方向直接变换,形成一个新的集合。

这个过程中,是不关心过程的,只关心从x到y的这个结果。而这个y很重要。所以,map必须有一个变量来接受新生成的这个y的集合。

同时,因为x到y的映射过程和第三者无关,所以在map的内部,不应该出现任何副作用(给函数外部的其他作用域中的变量赋值、输入、输出,包括网络请求等操作称为副作用)


换句话说:在学过map之前,大家都是用for和forEach来实现的功能,现在就应该还用for/forEach,只有在纯粹的把一个集合映射到另一个集合这一种场景下,大家才应该用map。


现在再回来看开头的那个例子,map有返回值是重点吗?不是。这个过程中出现了副作用,而且并没有把初始集合映射成任何新的集合(映射成了一个满是void的集合)

所以映射本身并不是重点,这就是一个普通的循环,理应直接用for/forEach,而不是选择map。


这样不知道是否解释清楚了呢?

Tags:

最近发表
标签列表