JS中数组方法map()的亿点点使用细节

前言

数组的map方法,大伙肯定都用过或者了解过,但你能准确的说出它的特性吗?它和forEach有什么区别?什么时候该用map?map里面写不写return?它有哪些坑?
看完这篇文章,再也不怕面试被问到^ - ^

特性介绍

直接放图,来自MDN的介绍:
map方法官方介绍
划重点,创建一个新数组,所以很多人都觉得map方法不会改变原数组,这个说法对也不对,下面会详细讲到。

和forEach的区别

它们最大的区别就是map有返回值,会返回一个新数组,而forEach只是针对数据。

let arr = [1,2,3]
let brr = arr.map(item => item += 1)
console.log(arr)  // [1,2,3]
console.log(brr)  // [2,3,4]
let crr = arr.forEach(item => item += 1)
console.log(arr)  // [1,2,3]
console.log(crr)  // undefined

ps:

  1. 这里map没有改变原数组
  2. map里没写return是因为,箭头函数只有一行是默认return的,多行时不写return是拿不到返回值的

什么时候用map

当你需要对数组每一项进行某些操作得到新数组时,常见于拿到请求返回的数组后进行一些过滤

this.request('/home/list', 'post', this.searchObj).then(res => {
	res.map(item => {
		if (item.sex === 1) {
			item.sex = '男'
		} else if (item.sex === 0) {
			item.sex = '女'
		}
	})
	this.list = res
})

细心的小伙伴可能发现了,这里既没用变量接收新数组,也没在map里写return,却能成功修改,这是为什么?

其实是因为如果数组中含有引用类型的数据,比如对象,这时候使用map改变对象的属性就会改变原数组。

let arr = [{ a: 1, b: 2}, { a: 5, b: 6 }]
arr.map(item => {
	if (item.a > 3) {
		item.a = 10
	}
	if (item.b < 5) {
		item.b = 3
	}
})
console.log(arr)  // [{ a: 1, b: 3 }, { a: 10, b: 6 }]

不知道这是map的bug呢,还是就这么设计的,欢迎懂哥留言。

总之正因为这样,才有了上面处理请求数组的使用方式,不用接收新数组,没有返回值,用最少的代码处理数组(forEach需要使用index去改变原数组),懒人直呼酸爽。

比较冷门的场景

我也是最近才遇到,需求是在一个数组的循环里用数组的某一项做异步事件的处理,然后需要在循环外拿到所有异步事件完成后的结果:

let arr = [...]
arr.forEach(item => {
	// 这里用settimeout代替异步事件
	setTimeout(() => {
      // 异步操作
    }, 500);
})

这里就可以使用map有返回值的特性,返回Promise数组,配合Promise.all解决:

let arr = [{ id: 1 }, { id: 2 }]
Promise.all(arr.map(item => {
	return new Promise((resolve, reject) => {
		settimeout(() => {
			resolve(// 异步操作)
		}, 500)
	})
})).then(() => console.log('操作后的结果'))

对你有帮助的话点个赞哦

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值