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

对你有帮助的话点个赞哦

<think>我们被要求使用中文回答,并且遵循特定的格式要求。 用户的问题:我想了解JavaScript数组map方法使用 请问JavaScript数组map方法详解及使用示例 根据引用[3]中提供的信息,我们有关于map方法的简单示例。同时,结合其他引用,我们可以更全面地介绍map方法。 回答结构: 1. 首先介绍map方法的基本概念和作用。 2. 语法说明。 3. 使用示例,包括基本示例和可能的复杂示例。 4. 注意事项或常见用法。 另外,根据系统指令,我们需要生成相关问题。 引用[3]的示例:const numbers = [1, 2, 3]; const doubled = numbers.map(num => num * 2); console.log(doubled); // [2, 4, 6](新数组) 我们还可以结合引用[1]和[2]中的信息,但引用[2]主要讲的是reduce,引用[4]提到了includes和sort,所以主要参考引用[1]和[3]。 注意:引用[1]提到“数组方法是内置工具,允许开发者高效地添加、删除、转换、迭代和搜索数组元素”,其中map属于转换和迭代。 步骤: 1. 介绍map方法map()方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。 2. 语法:arr.map(callback(currentValue[, index[, array]])[, thisArg]) 3. 参数说明:callback生成新数组元素的函数,可以接收三个参数:当前元素、当前元素的索引、原数组。thisArg(可选)执行callback时使用的this值。 4. 返回值:新数组,不改变原数组。 示例: - 基本示例:将数组中的每个元素乘以2。 - 使用索引:将元素乘以它的索引。 - 复杂示例:处理对象数组。 5. 注意事项:map不会改变原数组(但可以在callback中改变原数组,不过不推荐),map方法会跳过空位(但根据ES标准,空位会被保留,具体行为可能因环境而异)。 生成相关问题: 1. map方法和其他数组方法(如filter、reduce)有什么区别? 2. 如何在map方法使用thisArg参数? 3. map方法在异步编程中的应用? 注意:在回答中引用段落末尾添加引用标识,例如[^1]。由于引用[3]中提到了map,我们可以在介绍时引用。 开始回答:</think>### JavaScript 数组 map() 方法详解 `map()` 是 JavaScript 数组的核心迭代方法,用于**创建新数组**并**批量转换元素**。它不会修改原数组,而是返回一个包含转换结果的新数组[^3]。 #### 核心特性 1. **非破坏性**:原数组保持不变 2. **链式调用**:可与其他数组方法(如 `filter()`)组合 3. **元素转换**:对每个元素执行指定操作 4. **返回新数组**:长度始终等于原数组 #### 语法 ```javascript const newArray = arr.map(callback(currentValue[, index[, array]]) { // 返回转换后的元素 }[, thisArg]); ``` - **`callback`**:处理每个元素的函数(必需) - **`currentValue`**:当前处理的元素 - **`index`**:当前元素索引(可选) - **`array`**:原数组引用(可选) - **`thisArg`**:执行回调时的 `this` 值(可选) --- ### 使用示例 #### 基础数值转换 ```javascript const numbers = [1, 2, 3]; const squared = numbers.map(num => num ** 2); console.log(squared); // [1, 4, 9] ``` #### 对象数组重构 ```javascript const users = [ {id: 1, name: "Alice"}, {id: 2, name: "Bob"} ]; const userNames = users.map(user => user.name); console.log(userNames); // ["Alice", "Bob"] ``` #### 使用索引参数 ```javascript const letters = ['a', 'b', 'c']; const indexed = letters.map((char, idx) => `${idx}-${char}`); console.log(indexed); // ["0-a", "1-b", "2-c"] ``` #### 结合其他方法(链式调用) ```javascript const data = [5, 12, 8, 130]; const processed = data .filter(x => x > 10) // 先过滤 [12, 130] .map(x => x * 0.8); // 再转换 [9.6, 104] console.log(processed); // [9.6, 104] ``` --- ### 注意事项 1. **空元素处理**:稀疏数组中的空槽(empty)会保留但不会触发回调 ```javascript const arr = [1, , 3]; arr.map(x => x * 2); // [2, empty, 6] ``` 2. **避免副作用**:不应在回调中修改原数组(违反函数式编程原则) 3. **异步限制**:不能直接处理异步操作,需配合 `Promise.all()` ```javascript // 错误示例 const urls = ['url1', 'url2']; const results = urls.map(async url => await fetch(url)); // 返回Promise数组 // 正确做法 Promise.all(urls.map(url => fetch(url))); ``` --- ### 与类似方法对比 | 方法 | 返回类型 | 是否修改原数组 | 用途 | |------------|----------------|----------------|--------------------------| | `map()` | 新数组 | ❌ | 元素转换 | | `forEach()`| undefined | ❌ | 遍历操作(无返回值) | | `filter()` | 新数组(子集) | ❌ | 条件筛选 | | `reduce()` | 任意类型 | ❌ | 累积计算[^2] |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值