文章目录
前言
数组的
map
方法,大伙肯定都用过或者了解过,但你能准确的说出它的特性吗?它和
forEach
有什么区别?什么时候该用
map
?map里面写不写
return
?它有哪些坑?
看完这篇文章,再也不怕面试被问到^ – ^
特性介绍
直接放图,来自MDN的介绍:
划重点,
创建一个新数组
,所以很多人都觉得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:
- 这里map没有改变原数组
- 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('操作后的结果'))
对你有帮助的话点个赞哦