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

  • Post author:
  • Post category:其他




前言

数组的

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('操作后的结果'))

对你有帮助的话点个赞哦



版权声明:本文为Naaaano原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。