人人都会AI编程

常用方法分类:遍历、修改、查询、转换、排序

更新时间:2026-07-11

数组是 JavaScript 中最频繁使用的数据结构,掌握数组方法的前端开发效率会大幅提升。根据使用目的,可以将常用数组方法归纳为五类。下面逐个梳理每种方法的核心用途、返回值和注意事项。


一、遍历:逐个访问数组元素

遍历方法的核心是“对每个元素执行一个函数”,但它们的行为和返回值各不相同。

1. forEach —— 最纯粹的遍历

对每个元素执行回调,没有返回值(返回 undefined),无法中途 breakreturn 跳出。

const arr = [1, 2, 3];
arr.forEach((item, index) => {
  console.log(`第${index}项:${item}`);
});
// 输出:
// 第0项:1
// 第1项:2
// 第2项:3

实用建议:适用于纯粹的副作用(如打印、修改外部变量)。需要提前终止循环时,使用 for...of 或传统 for 循环。

2. map —— 遍历并映射为新数组

对每个元素执行回调,返回一个新数组,新数组的每一项是回调函数的返回值。不会改变原数组。

const nums = [1, 2, 3];
const doubled = nums.map(n => n * 2); // [2, 4, 6]

常见误区:只遍历无映射需求时用 forEach,不要用 map 而忽略其返回值。

3. filter —— 遍历并过滤

返回一个新数组,只包含使回调返回 true 的元素

const nums = [1, 2, 3, 4];
const evens = nums.filter(n => n % 2 === 0); // [2, 4]

4. some / every —— 条件测试遍历

  • some:只要有一个元素通过测试就返回 true
  • every:所有元素都通过测试才返回 true
const arr = [1, 2, 3];
arr.some(n => n > 2);    // true
arr.every(n => n > 0);   // true
arr.every(n => n > 2);   // false

实用建议someevery 存在“短路”机制,一旦结论确定就停止遍历,比遍历所有元素再判断更高效。


二、修改:增删改原数组

这类方法会直接改变原数组,使用时要留意副作用。

1. push / pop —— 末尾添加/删除

const arr = [1, 2];
arr.push(3);     // 返回新长度 3,arr 变为 [1,2,3]
arr.pop();       // 返回被删除的元素 3,arr 变回 [1,2]

2. shift / unshift —— 头部删除/添加

const arr = [2, 3];
arr.unshift(1);  // 返回新长度 3,arr 变为 [1,2,3]
arr.shift();     // 返回被删除的元素 1,arr 变回 [2,3]

性能警告shiftunshift 会移动所有后续元素,时间复杂度 O(n),大数组慎用。

3. splice —— 任意位置增删改

功能强大,原数组被修改,返回值是删除的元素(若无删除则为空数组)。

const arr = [1, 2, 3, 4];
// 删除从索引1开始的2个元素
const removed = arr.splice(1, 2);  // removed = [2,3], arr 变为 [1,4]

// 在索引1处插入元素
arr.splice(1, 0, 5, 6);  // arr 变为 [1,5,6,4]

4. fill —— 填充数组

用固定值覆盖数组元素,返回修改后的原数组。

const arr = [1, 2, 3];
arr.fill(0);          // [0, 0, 0]
arr.fill(9, 1, 2);    // 从索引1到2(不含),填充为9:[0, 9, 0]

三、查询:查找元素或索引

1. indexOf / lastIndexOf —— 查找某值的索引

严格相等比较(===),返回首次匹配索引,找不到返回 -1

const arr = [1, 2, 3, 2];
arr.indexOf(2);       // 1
arr.lastIndexOf(2);   // 3
arr.indexOf(4);       // -1

2. includes —— 判断是否包含某值

返回 truefalse,使用严格相等比较。ES7 新增,比 indexOf 语义更清晰。

[1, 2, 3].includes(2);  // true
[1, 2, 3].includes(4);  // false

3. find / findIndex —— 按条件查找

  • find:返回第一个让回调返回 true元素本身,找不到返回 undefined
  • findIndex:返回对应的索引,找不到返回 -1
const users = [
  { name: 'Alice', age: 20 },
  { name: 'Bob', age: 25 }
];
users.find(u => u.age > 21);      // { name: 'Bob', age: 25 }
users.findIndex(u => u.age > 21); // 1

优势:查找对象数组时远比 indexOf 灵活。


四、转换:生成新数组或聚合为单个值

1. concat —— 合并数组

返回新数组,不改变原数组。

[1, 2].concat([3, 4]); // [1, 2, 3, 4]
// 也可以使用展开运算符:[...[1,2], ...[3,4]]

2. slice —— 截取子数组

返回新数组,包含起止索引之间的元素(不含结束索引)。原数组不变。

const arr = [1, 2, 3, 4];
arr.slice(1, 3); // [2, 3]
arr.slice(1);    // [2, 3, 4],省略结束索引则到末尾

3. join —— 数组转字符串

将数组元素用指定分隔符连接成字符串。元素为 undefined/null 时会转为空字符串。

[1, 2, 3].join('-');   // "1-2-3"
['H', 'i'].join('');   // "Hi"

4. reduce / reduceRight —— 聚合为单个值

从左(或右)累积计算,回调接收累加器和当前值。返回值可以是任意类型

const nums = [1, 2, 3, 4];
const sum = nums.reduce((acc, cur) => acc + cur, 0); // 10

强大之处:除了求和,还可以扁平化数组、按条件分组、组合函数等。

5. flat / flatMap —— 数组扁平化

  • flat(depth):拉平嵌套数组,默认深度 1。
  • flatMap:先 mapflat(深度 1),常用于将每个元素映射成一个数组后再合并。
[1, [2, [3]]].flat(2);          // [1, 2, 3]
[1, 2, 3].flatMap(n => [n, n*2]); // [1, 2, 2, 4, 3, 6]

五、排序与反转

1. sort —— 排序数组

直接修改原数组,返回排序后的原数组引用。默认按字符串 Unicode 排序,数字排序必须传入比较函数。

const arr = [3, 1, 4, 1, 5];
arr.sort();                   // [1, 1, 3, 4, 5](按字符序)

// 数字正确排序
[10, 2, 1].sort((a, b) => a - b); // [1, 2, 10]
[10, 2, 1].sort((a, b) => b - a); // [10, 2, 1](降序)

2. reverse —— 反转顺序

修改原数组,返回原数组引用。

const arr = [1, 2, 3];
arr.reverse(); // [3, 2, 1]

使用建议与避坑指南

| 分类 | 方法 | 是否修改原数组 | 返回值 | 关键注意点 |
|------|------|---------------|--------|------------|
| 遍历 | forEach | 否 | undefined | 无法中途跳出 |
| 遍历 | map | 否 | 新数组 | 新数组长度与原数组一致 |
| 遍历 | filter | 否 | 新数组 | 仅保留条件为 true 的元素 |
| 修改 | push/pop | 是 | 新长度/删除元素 | 未尾操作,O(1) |
| 修改 | shift/unshift | 是 | 新长度/删除元素 | 头部操作,O(n),大数组慎用 |
| 修改 | splice | 是 | 删除的元素数组 | 可增可删可改 |
| 查询 | indexOf/includes | 否 | 索引/布尔 | 严格相等比较 |
| 查询 | find/findIndex | 否 | 元素/索引 | 按条件查找,灵活 |
| 转换 | concat/slice/join | 否 | 新数组/字符串 | 不改变原数组 |
| 转换 | reduce | 否 | 任意值 | 功能极其强大 |
| 排序 | sort/reverse | | 原数组引用 | 直接修改原数组! |

核心原则:需要保留原数组时,先手动拷贝([...arr]arr.slice()),再调用修改类方法。善用 mapfilterreduce 的组合完成复杂数据处理,避免大量副作用代码。