一、前言

forEach和map是数组的两个方法,作用都是遍历数组。在vue项目的处理数据中经常会用到,这里介绍一下两者的区别和具体用法示例。

二、代码

1. 相同点

  1. 都是数组的方法
  2. 都用来遍历数组
  3. 两个函数都有4个参数:匿名函数中可传3个参数item(当前项), index(当前项的索引), arr(原数组),还有一个可选参数this
  4. 匿名函数中的this默认是指向window的
  5. 对空数组不会调用回调函数
  6. 不会改变原数组(某些情况下可改变)

2. forEach

(1) 没有返回值。

var a = [1,2,3,4,5]
var b = a.forEach((item) => {item = item * 2
})
console.log(b)
// undefiined

(2) 可改变原数组的情况

下面来看几个例子:

var a = [1,2,3,4,5]
a.forEach((item) => {item = item * 2
})
console.log(a)
// [1,2,3,4,5]

这里原数组并没有发生改变。

var a = [1,'1',{num:1},true]
a.forEach((item, index, arr) => {item = 2
})
console.log(a)
// [1,'1',{num:1},true]

这里修改item的值,依然没有修改原数组。

var a = [1,'1',{num:1},true]
a.forEach((item, index, arr) => {item.num = 2item = 2
})
console.log(a)
// [1,'1',{num:2},true]

当修改数组中对象的某个属性时,发现属性改变了。

为什么会这样呢?
这里就要引入栈(stack)内存和堆(heap)内存的概念了,对于JS中的基本数据类型,如String,Number,Boolean,Undefined,Null是存在于栈内存中的,在栈内存中储存变量名及相应的值。而Object,Array,Function存在于堆内存中,在堆内存中储存变量名及引用位置。

在第一个例子中,为什么直接修改item无法修改原数组呢,因为item的值并不是相应的原数组中的值,而是重新建立的一个新变量,值和原数组相同。
在第二个例子中,数组中的对象的值也没有改变,是因为新创建的变量和原数组中的对象虽然指向同一个地址,但改变的是新变量的值,即新对象的值为2,原数组中的对象还是{num:1}。
在第三个例子中,由于对象是引用类型,新对象和旧对象指向的都是同一个地址,所以新对象把num变成了2,原数组中的对象也改变了。

var a = [1,2,3,4,5]
a.forEach((item, index, arr) => {arr[index] = item * 2
})
console.log(a)
// [2,4,6,8,10]

在回调函数里改变arr的值,原数组改变了。

这个例子和例三其实同理,参数中的arr也只是原数组的一个拷贝,如果修改数组中的某一项则原数组也改变因为指向同一引用地址,而如果给参数arr赋其他值,则原数组不变。

其实想要知道参数中的item和arr是不是重新创建的变量,在回调函数中打印就知道了。

(3) vue中的应用

在处理数据时我经常用到这个方法,因为数据的传递以json格式,经常会收到数组中包含许多对象的数据。而后端传给我的数据有时候需要处理,例如把时间戳格式化为正常时间,代码如下:

// utils.js
const formatTime = date => {var newDate = new Date();newDate.setTime(date * 1000);const year = newDate.getFullYear()const month = newDate.getMonth() + 1const day = newDate.getDate()const hour = newDate.getHours()const minute = newDate.getMinutes()const second = newDate.getSeconds()return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}const formatNumber = n => {n = n.toString()return n[1] ? n : '0' + n
}export {formatTime
}
// 得到的数据格式
[{add_time: 1541495677, balance: 14, bn: "300708", cprice: "12.39"}
]
// index.vue
import axios from 'axios'
import { formatTime } from '@/lib/utils'
export default {data() {dataList: []},methods: {getData() {axios.get('/user?ID=12345').then(function (res) {if(res.code == 200) {res.data.forEach((item) => {item.add_time = formatTime(item.add_time)}this.dataList = res.data}}).catch(function (err) {console.log(err);});}}
}

这时候原始数据的值也改变了,变成了格式化后的时间。

3. map

(1) 返回一个经过处理后的新数组,但不改变原数组的值。

var a = [1,2,3,4,5]
var b = a.map((item) => {return item = item * 2
})
console.log(a)  // [1,2,3,4,5]
console.log(b)  // [2,4,6,8,10]

(2) map中可改变原数组的情况和原理与forEach相同

(3) vue中的应用

有这样一个需求,充值金额需要在整数的基础上随机减去100或加上100,这时我在原始的数据基础上需要一个经过处理的新数组。

export default {data() {moneyList: [1000,2000,5000,10000,20000,50000]},computed: {moneyList_new() {return this.moneyList.map((item) => {const random = Math.random() > 0.5 ? 1 : -1;return Math.floor(Math.random()*100) * random + item;})}}
}

实际渲染处理过的数组就可以了~

三、结语

以上就是forEach和map的对比与实际应用,代码只是演示使用方法并非完全真实。

vue 数组遍历方法forEach和map的原理解析和实际应用相关推荐

  1. ES5 数组扩展方法 forEach/filter/map的使用与重写

    ES3 splice slice join sort (IE5.IE6) 数组扩展方法 ES5(在ES3的基础上增加.修正) forEach 可能会改变原数组(直接操作了arr[i],没有使用深拷贝) ...

  2. js 数组遍历方法详解(map、filter、find、findIndex、reduce)

    目录 前言 map map是什么 map方法的结构及入参 语法糖 map一般不改变原数组 filter 说明 例子 find 和 findIndex 说明 例子 reduce 说明 例子 尾言 前言 ...

  3. php的遍历方法,PHP数组遍历方法总结

    在PHP中数组分为两类: 数字索引数组和关联数组. 其中数字索引数组和C语言中的数组一样,下标是为0,1,2- 而关联数组下标可能是任意类型,与其它语言中的hash,map等结构相似. 下面介绍PHP ...

  4. ES5和ES6数组遍历方法详解

    ES5和ES6数组遍历方法详解 在ES5中常用的10种数组遍历方法: 1.原始的for循环语句 2.Array.prototype.forEach数组对象内置方法 3.Array.prototype. ...

  5. js数组遍历方法总结与对比

    目录 总结 一.常规方法 for的4种写法 while 二.ES6方法 for...of,得到每项元素 for...in,得到的是数组索引 三.数组实例上的遍历方法 forEach(),得到每一项元素 ...

  6. ES6中新增数组遍历方法

    ES6中新增的方法 遍历方法: forEach(),fifter(),some(): array.forEach(function(currentValue,index,arr)) // curren ...

  7. 浅谈JS的数组遍历方法

    用过Underscore的朋友都知道,它对数组(集合)的遍历有着非常完善的API可以调用的,_.each()就是其中一个.下面就是一个简单的例子: var arr = [1, 2, 3, 4, 5]; ...

  8. 数组中的forEach和map的区别

    大多数情况下,我们都要对数组进行遍历,然后经常用到的两个方法就是forEach和map方法. 先来说说它们的共同点 相同点 都是循环遍历数组中的每一项 forEach和map方法里每次执行匿名函数都支 ...

  9. js 数组遍历符合条件跳出循环体_Js数组遍历方法对比总结

    引言: ES6为javascript为数组遍历提供了新的一种方式: for....of.....那之前的遍历方法各存在哪些缺点?for...of...有什么好处?接下来,我们先回顾一下有多少种方式. ...

  10. JavaScript 数组遍历方法的对比

    前言 JavaScript 发展至今已经发展出多种数组的循环遍历的方法,不同的遍历方法运行起来那个比较快,不同循环方法使用在那些场景,下面将进行比较: 各种数组遍历的方法 for 语句 代码: var ...

最新文章

  1. 非对称加密和证书总结
  2. 【Android 逆向】Android 权限 ( ro.product.cpu.abi 属性 | ro.zygote 属性 | dhcp.eth0 属性 | net.* 属性 )
  3. GitLab远程仓库迁移
  4. Android Studio目录结构分析
  5. c语言 java 性能 测试_这个蓝桥杯系统的题,用c语言去评测是满分,改为Java说运行错误是0分,但是我查看输入输出,至少第...
  6. 分段函数if语句_C语言函数系列之库函数中基础必会函数(一)
  7. Linux关闭Tomcat服务器出现无法关闭 :8005端口未启动
  8. LVS原理详解及部署之四:keepalived介绍
  9. uml定义的使用的关系
  10. [arduino]-序言:面向仅有C语言基础之人的单片机开发板
  11. 手机自学html,5套Bootstrap手机模板HTML源文件分享
  12. android全面屏像素密度,屏幕像素密度超400ppi,让你感受视觉的极限
  13. 今天Sapphire来短消息问我“一件有点隐私”的事情,:)
  14. 计算物体自由下落的距离
  15. 这341句话,这么美,那么伤。
  16. LabVIEW概述及其优点
  17. MacOS安装npm
  18. 计算机u盘序列号,win10-u盘序列号cmd怎么查
  19. C/C++中的ctime用法总结
  20. RFID读写器的组成

热门文章

  1. 真·不怪云原生:探寻IT大厂逐渐云化的秘密!
  2. Android系统级深入开发——移植与调试
  3. 5.4 tensorflow2实现消除多重共线性、人均网络消费回归分析——python实战
  4. Matplotlib Toolkits:地图绘制工具
  5. 【ffmpeg】不带透明通道的视频overlay
  6. python分组和任务分配_python-使用Celery在多个队列中公平分配任务
  7. 网页开发者模式调整到手机模式_苹果全球开发者大会将于6月22日召开 全线上模式...
  8. 笔记本显示网络电缆被拔出怎么解决_电脑显示“网络电缆被拔出”怎么办?
  9. delphi 中文转 ascii编码_【转】Python 中文编码
  10. import matplotlib 出现“No module named 'pyparsing'“问题