译者按: 惯用Haskell的我更爱map。

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。

如果你已经有使用JavaScript的经验,你可能已经知道这两个看似相同的方法:Array.prototype.map()Array.prototype.forEach()

那么,它们到底有什么区别呢?

定义

我们首先来看一看MDN上对Map和ForEach的定义:

  • forEach(): 针对每一个元素执行提供的函数(executes a provided function once for each array element)。
  • map(): 创建一个新的数组,其中每一个元素由调用数组中的每一个元素执行提供的函数得来(creates a new array with the results of calling a provided function on every element in the calling array)。

到底有什么区别呢?forEach()方法不会返回执行结果,而是undefined。也就是说,forEach()会修改原来的数组。而map()方法会得到一个新的数组并返回。

示例

下方提供了一个数组,如果我们想将其中的每一个元素翻倍,我们可以使用mapforEach来达到目的。

let arr = [1, 2, 3, 4, 5];

ForEach

注意,forEach是不会返回有意义的值的。
我们在回调函数中直接修改arr的值。

arr.forEach((num, index) => {
return arr[index] = num * 2;
});

执行结果如下:

// arr = [2, 4, 6, 8, 10]

Map

let doubled = arr.map(num => {
return num * 2;
});

执行结果如下:

// doubled = [2, 4, 6, 8, 10]

执行速度对比

jsPref是一个非常好的网站用来比较不同的JavaScript函数的执行速度。

这里是forEach()map()的测试结果:

可以看到,在我到电脑上forEach()的执行速度比map()慢了70%。每个人的浏览器的执行结果会不一样。你可以使用下面的链接来测试一下: Map vs. forEach - jsPref

JavaScript太灵(gui)活(yi)了,出了BUG你也不知道,不妨接入Fundebug线上实时监控

函数式角度的理解

如果你习惯使用函数是编程,那么肯定喜欢使用map()。因为forEach()会改变原始的数组的值,而map()会返回一个全新的数组,原本的数组不受到影响。

哪个更好呢?

取决于你想要做什么。

forEach适合于你并不打算改变数据的时候,而只是想用数据做一些事情 – 比如存入数据库或则打印出来。

let arr = ['a', 'b', 'c', 'd'];
arr.forEach((letter) => {
console.log(letter);
});
// a
// b
// c
// d

map()适用于你要改变数据值的时候。不仅仅在于它更快,而且返回一个新的数组。这样的优点在于你可以使用复合(composition)(map(), filter(), reduce()等组合使用)来玩出更多的花样。

let arr = [1, 2, 3, 4, 5];
let arr2 = arr.map(num => num * 2).filter(num => num > 5);
// arr2 = [6, 8, 10]

我们首先使用map将每一个元素乘以2,然后紧接着筛选出那些大于5的元素。最终结果赋值给arr2

核心要点

  • 能用forEach()做到的,map()同样可以。反过来也是如此。
  • map()会分配内存空间存储新数组并返回,forEach()不会返回数据。
  • forEach()允许callback更改原始数组的元素。map()返回新的数组。
版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2018/02/05/map_vs_foreach/

JavaScript中Map和ForEach的区别的更多相关文章

  1. JS中map与forEach的区别

    很多同学可能对于map与forEach的区别不是太了解,今天我们介绍一下JS中的map与forEach方法, 我对map的理解是,这个方法对一个数组arr1中的每一个元素进行遍历(传递给一个数组,参数 ...

  2. JavaScript 中 map、foreach、reduce 间的区别

    一直对map.foreach.reduce这些函数很是生疏,今天看underscorejs时好好研究了一下,一研究我就更懵了,这不是一样嘛,都是遍历,所以我就去知乎找了一下,整理出了比较好的几个说法. ...

  3. ES5中, map 和 forEach的区别

    forEach和map区别在哪里知道吗? // forEach Array.prototype.forEach(callback(item, index, thisArr), thisArg) // ...

  4. Javascript的map与forEach的区别

    原理: 高级浏览器支持forEach方法语法:forEach和map都支持2个参数:一个是回调函数(item,index,list)和上下文: forEach:用来遍历数组中的每一项:这个方法执行是没 ...

  5. JS中map和foreach的区别以及some和every的用法

    一.原生JS forEach()和map()遍历 共同点: 1.都是循环遍历数组中的每一项. 2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前 ...

  6. JS中Map和ForEach的区别

    定义 forEach()方法: 针对每一个元素执行提供的函数. map()方法: 创建一个新的数组,其中每一个元素由调用数组中的每一个元素执行提供的函数得来. 区别 forEach()方法不会返回执行 ...

  7. JS中map()与forEach()的区别和用法

    相同点: 1.都是循环遍历数组中的每一项 2.每次执行匿名函数都支持三个参数,参数分别为item(当前每一项),index(索引值),arr(原数组) 3.匿名函数中的this都是指向window 4 ...

  8. JavaScript中:表达式和语句的区别

    JavaScript中:表达式和语句的区别 Javascript语言精粹:表达式是由运算符构成,并运算产生结果的语法结构.程序是由语句构成,语句则是由“:(分号)”分隔的句子或命令.如果在表达式后面加 ...

  9. 原 c++中map与unordered_map的区别

    c++中map与unordered_map的区别 头文件 map: #include < map > unordered_map: #include < unordered_map ...

随机推荐

  1. Jenkins关闭和重启实现方式.

    1.关闭Jenkins 只需要在访问jenkins服务器的网址url地址后加上exit.例如我jenkins的地址http://localhost:8080/,那么我只需要在浏览器地址栏上敲下http ...

  2. Akka-CQRS(3)- 再想多点,全面点

    上篇我介绍了CQRS模式存写部分的具体实现和akka-persistence一些函数和消息的用法.在这篇本来是准备直接用一个具体的例子来示范CQRS模式编程,主要是写端,或者是数据采集端.想着模拟收银 ...

  3. Java核心技术卷一基础知识-第10章-部署应用程序和applet-读书笔记

    第10章 部署应用程序和applet 本章内容: * JAR文件 * Java Web Start * applet * 应用程序首选项存储 10.1 JAR文件 一个JAR文件既可以包含类文件,也可 ...

  4. 微信小程序客服消息新增临时素材接口java实现

    今天想在微信小程序的客服信息窗口里回复用户一个图片信息,发现还需要上传素材,但是微信文档的上传临时素材接口写的模模糊糊,无奈去百度,网上清一色的PHP实现方式,难道我穿越了?PHP已经把java给超越 ...

  5. 第73节:Java中的HTTPServletReauest和HTTPServletResponse

    第73节:Java中的HTTPServletReauest和HTTPServletResponse HTTP协议 客户端与服务器端通讯的一种规则. request: 请求行 请求头 请求体 respo ...

  6. Redis 指令 学习笔记

    Redis 什么是Redis redis是一种nosql数据库,他的数据是保存在内存中,同时redis可以定时把内存数据同步到磁盘,即可以将数据持久化,还提供了多个语言的API,操作比较方便 安装re ...

  7. 一个需求认识CSS3 的transform-origin属性

    最近遇到一个需求,是以前做PHP的同事问我的问题    下面是他在百度发的问题截图 根据上面的截图,我稍微梳理了一下 问题:现在有个div,旋转45度后,这个div的宽度会动态改变,并且要向右上方偏移 ...

  8. 选择IT事业,意味着终身学习

    八月,炎阳如火. 前几天书记找我交流,问我离职的原因,我跟他仔细的分析了一下我的职业发展规划和我对于未来的预期,书记也向我分析了一下他所认为的原因,他说,无外乎是三个原因:第一个是钱的问题:第二个是行 ...

  9. Android获取手机号码

    今天来说一下Android系统中怎么获取手机号 一.SIM卡存储的数据可分为四类,它们分别是: 第一类是固定存放的数据.这类数据在移动电话机被出售之前由SIM卡中心写入,包括国际移动用户识别号(IMS ...

  10. spring boot整合 springmvc+mybatis

    需要以下依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId&g ...