map方法不操作原对象属性,而是通过回调函数实现属性提取、不可变更新、条件修改及上下文处理;常见用法包括提取字段、展开复制构造新对象、条件返回、利用索引或原数组增强逻辑。

map 方法本身不操作对象属性,但它常被用来访问、提取或更新数组中每个对象的属性。关键在于回调函数怎么写——它决定你是在读取、变形,还是浅层修改对象结构。
提取对象的某个属性生成新数组
这是最常见用法。遍历对象数组,只取其中某一个字段,形成纯值数组。
- 用点号直接访问:
users.map(u => u.name) - 支持解构写法更清晰:
users.map(({ name }) => name) - 若属性可能为 undefined,可加默认值:
users.map(u => u.email || '未知邮箱')
基于原对象构造新对象(推荐的不可变方式)
想保留原数组不变,同时更新某些属性,应返回一个新对象,而不是改原对象。
- 用展开运算符复制再覆盖:
data.map(item => ({ ...item, age: item.age + 1 })) - 只保留部分字段也适用:
data.map(({ id, name }) => ({ id, fullName: name })) - 避免直接修改原对象,否则副作用难追踪,尤其在 React 等框架中容易引发渲染问题
条件性更新特定对象的属性
当需要根据条件(如 id 匹配)更新数组中某一个对象时,map 仍适用,但需在回调里做判断。
- 匹配成功就返回新对象,否则返回原对象:
list.map(item => item.id === targetId ? { ...item, status: 'done' } : item) - 注意不要漏掉
return item,否则其他元素会变成undefined - 这种写法天然保持数组长度和顺序,比 filter + concat 更直观安全
配合索引或原始数组做上下文处理
map 的回调函数默认传入三个参数:当前项、索引、整个数组。有时属性值依赖位置或其他全局信息。
- 添加序号字段:
items.map((item, i) => ({ ...item, order: i + 1 })) - 引用原数组做关联判断:
arr.map((x, i, a) => ({ ...x, isLast: i === a.length - 1 })) - 注意 thisArg 参数较少用,一般用箭头函数或显式绑定更可控










