map 返回新数组且不修改原数组,长度严格一致;回调函数接收三个参数(值、索引、原数组);错误会抛出而非静默;应避免与 filter 混用,性能差异通常可忽略。

map 返回的是新数组,不是原地修改
调用 map 不会改变原数组,它总是返回一个全新数组,长度和原数组严格一致——哪怕回调函数返回 undefined 或 null,对应位置也会保留该值,不会跳过或缩短。这点和 filter 有本质区别。
常见错误是误以为 map 能“过滤+映射”一起做,结果得到一堆 undefined 却没意识到长度没变:
const arr = [1, 2, 3, 4]; const doubledOdds = arr.map(x => x % 2 === 0 ? x * 2 : undefined); // → [undefined, 4, undefined, 8],长度仍是 4
- 要过滤再映射,得先
filter再map,或用flatMap配合条件返回单元素数组/空数组 - 如果回调里抛错,
map会中断并把错误抛出,不会静默吞掉 - 空位(sparse array)在
map中会被跳过,但现代引擎对稀疏数组行为不统一,建议避免依赖
回调函数的三个参数:不只是当前元素
map 回调默认接收三个参数:currentValue、index、array。很多人只用第一个,但后两个在实际场景中很关键:
- 需要按位置做不同处理时(比如偶数索引乘 2,奇数索引加 1),必须用
index - 需要访问原数组其他元素(如计算相邻差值),靠
array参数比闭包引用更清晰安全 - 箭头函数写法别漏掉括号:
[1,2].map((x,i) => x+i)正确;[1,2].map(x,i => x+i)错——第二个参数会被当成箭头函数体的一部分
map 和 for 循环性能差异没你想的那么大
在多数业务场景下,map 和手写 for 循环的性能差距可以忽略。V8 等引擎对 map 有专门优化,且语义明确、不易出错。
- 真有性能瓶颈时,通常卡在回调函数内部逻辑(比如频繁 DOM 操作、深克隆),而不是
map本身 - 如果只是遍历+副作用(如发请求、改 DOM),别硬套
map——用forEach更语义清晰,也避免产生无用新数组 - 超大数组(>10 万项)且回调简单时,
for可能略快,但应先实测,而非预设
类型系统里 map 的泛型容易被忽略
TypeScript 中,map 的返回类型由回调函数返回值推导。如果回调可能返回多种类型(比如 string | number),新数组类型就是联合类型的数组,不是 any[]。
- 显式标注回调返回类型可提升可读性:
arr.map((x): string => x.toString()) - 如果原数组含
undefined或空位,TS 默认不认为它们是数组合法成员,需用Array<t undefined></t>显式声明 - 在 strictNullChecks 下,回调若没处理
undefined分支,TS 会报错——这反而是好事,暴露了边界情况
最常被绕开的其实是稀疏数组和 callback 抛错这两点,实际项目里一旦出问题,往往卡在这儿。

















