一、前言

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 = 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;
})
}
}
}

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

三、结语

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

原文地址:https://segmentfault.com/a/1190000017011454

vue 数组遍历方法forEach和map的原理解析和实际应用的更多相关文章

  1. 数组遍历方法forEach 和 map 的区别

    数组遍历方法forEach 和 map 的区别:https://www.cnblogs.com/sticktong/p/7602783.html

  2. 数组的方法 forEach filter map slice splice

    目前一些数组的实用的方法 1 arr.splice(i,n) 删除从i(索引值)开始之后的那个元素.返回值是删除的元素,改变原数组: 参数: i 索引值      n 个数 let arr = [1, ...

  3. ES6 数组遍历方法的实战用法总结(forEach,every,some,map,filter,reduce,reduceRight,indexOf,lastIndexOf)

    目录 forEach every some map filter reduce && reduceRight indexOf lastIndexOf 前言 ES6原生语法中提供了非常多 ...

  4. js数组遍历方法总结

    数组遍历方法 1.for循环 使用临时变量,将长度缓存起来,避免重复获取数组长度,当数组较大时优化效果才会比较明显. 1 2 3 for(j = 0,len=arr.length; j < le ...

  5. JS数组遍历方法

    常用数组遍历方法: 1.原始for循环 var a = [1,2,3]; for(var i=0;i<a.length;i++){ console.log(a[i]); //结果依次为1,2,3 ...

  6. 浅谈6种JS数组遍历方法的区别

    本篇文章给大家介绍一下6种JS数组遍历方法:for.foreach.for in.for of.. each. ().each的区别.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. ...

  7. vue数组变异方法

    Vue数组变异方法,会改变被这些方法调用的原始数组,将会触发视图更新 push() 接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度 pop() 从数组末尾移除最后一项,减少数组的 ...

  8. js几种数组遍历方法.

    第一种:普通的for循环 ; i < arr.length; i++) { } 这是最简单的一种遍历方法,也是使用的最多的一种,但是还能优化. 第二种:优化版for循环 ,len=arr.len ...

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

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

随机推荐

  1. Spring MVC 返回 xml json pdf 数据的配置方法

    <!-- Spring MVC 返回 xml 数据的配置方法 -->     <bean class="org.springframework.web.servlet.vi ...

  2. c语言解决函数变参数问题 va_list

    前言:看到sprintf,swprintf之类的可变参数格式化函数,是否想过我们能写一个自定义的类似的函数吗?答案是很定的,下面来介绍一种方法,用va_list,va_start, va_end来实现 ...

  3. /etc/vimrc配置

    [root@guolicheng ~]# cat /etc/vimrc if v:lang =~ "utf8$" || v:lang =~ "UTF-8$" s ...

  4. GDKOI2018游记 and 总结

    前言 前年NOIP普及组考炸了,没考进一等奖,导致去年只能参加NOIP普及组. 去年NOIP普及组考炸了,幸好进了一等奖. 今年的GDKOI名额是难得的,这是我第一次参加Day>=2的比赛. 第 ...

  5. PostgreSQL 优化器代码概览

    简介 PostgreSQL 的开发源自上世纪80年代,它最初是 Michael Stonebraker 等人在美国国防部支持下创建的POSTGRE项目.上世纪末,Andrew Yu 等人在它上面搭建了 ...

  6. BZOJ 2683: 简单题(CDQ 分治)

    题面 Time Limit: 50 Sec  Memory Limit: 128 MB Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: ...

  7. php表单 - 验证邮件和URL

    PHP - 验证名称 以下代码将通过简单的方式来检测 name 字段是否包含字母和空格,如果 name 字段值不合法,将输出错误信息: $name = test_input($_POST[" ...

  8. (转)AngularJS判断checkbox/复选框是否选中并实时显示

    最近做了一个选择标签的功能,把一些标签展示给用户,用户选择自己喜欢的标签,就类似我们在购物网站看到的那种过滤标签似的: 简单的效果如图所示: 首先看一下html代码: <!DOCTYPE htm ...

  9. 【Redis安装】部署与基本配置 --基于Mac和Linux

    Redis安装与部署[基于Mac和Linux] 一.Redis简介 基于内存的Key-Value高性能NoSQL数据库 二.Redis下载和解压 进入官网下载最新版的Redis,目前是5.0.0,这个 ...

  10. 【DM8168学习笔记3】CodSourcery GCC Tool Chain安装过程记录

    eagle@eagle-desktop:~$ cd/home/eagle/desktop eagle@eagle-desktop:~/desktop$ cd./vboxshared eagle@eag ...