详解vue数组遍历方法forEach和map的原理解析和实际应用

作者:Peggy7 时间:2024-05-05 09:06:18 

一、前言

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

二、代码

1. 相同点

  • 都是数组的方法

  • 都用来遍历数组

  • 两个函数都有4个参数:匿名函数中可传3个参数item(当前项), index(当前项的索引), arr(原数组),还有一个可选参数this

  • 匿名函数中的this默认是指向window的

  • 对空数组不会调用回调函数

  • 不会改变原数组(某些情况下可改变)

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 = 2
 item = 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() + 1
 const 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;
     })
   }
 }
}

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

三、结语

来源:https://segmentfault.com/a/1190000017011454

标签:vue,forEach,map
0
投稿

猜你喜欢

  • python网络爬虫精解之pyquery的使用说明

    2021-05-28 13:01:19
  • python实现图片上添加图片

    2022-01-13 19:19:05
  • selenium中常见的表单元素操作方法总结

    2021-06-15 23:54:32
  • MySQL单表ibd文件恢复方法详解

    2024-01-15 19:39:21
  • Window 7/XP 安装Apache 2.4与PHP 5.4 的过程详解

    2023-11-24 09:28:09
  • Pandas多列值合并成一列的实现

    2023-02-13 08:39:44
  • Python计算一个点到所有点的欧式距离实现方法

    2023-03-29 21:19:11
  • Python 利用argparse模块实现脚本命令行参数解析

    2022-12-01 16:11:55
  • 移动测试开发Mitmproxy用于测试抓包神器详解

    2023-08-30 23:34:55
  • Python实现网络端口转发和重定向的方法

    2023-09-23 10:19:59
  • Active Server Pages 错误 “ASP 0141”

    2009-08-19 17:10:00
  • JavaScript获取中英文混合字符串长度的方法示例

    2024-05-02 16:27:25
  • Python实现改变与矩形橡胶的线条的颜色代码示例

    2022-08-02 08:16:26
  • 详解golang碎片整理之 fmt.Scan

    2024-02-20 12:51:16
  • Python中操作各种多媒体,视频、音频到图片的代码详解

    2021-09-25 21:47:49
  • 从8个方面优化ASP代码

    2007-09-16 18:01:00
  • 几款好用的前端开发编辑器推荐安利

    2023-11-21 13:30:00
  • python 同时读取多个文件的例子

    2022-06-27 03:56:50
  • Mysql优化策略(推荐)

    2024-01-19 15:18:34
  • Python中使用 Selenium 实现网页截图实例

    2022-07-04 06:28:16
  • asp之家 网络编程 m.aspxhome.com