在 JavaScript 中,数组是最常用的数据结构之一。
无论是前端开发、Node.js、接口数据处理,还是日常刷题,数组方法几乎都会频繁出现。
很多初学者在学习数组时,经常会遇到几个问题:
- 数组方法太多,记不住
forEach、map、filter很容易混- 哪些方法会修改原数组,哪些不会
- 遇到实际题目时,不知道该选哪个方法
这篇文章就从"先总览、再分类、再练习"的方式,系统总结 JavaScript 中常见的数组方法。
数组方法总览表
先别急着一个一个啃,先看一张总表,建立整体印象。
| 方法 | 作用 | 返回值 | 是否修改原数组 |
|---|---|---|---|
forEach() |
遍历数组并执行操作 | undefined |
否 |
map() |
映射生成新数组 | 新数组 | 否 |
filter() |
筛选符合条件的元素 | 新数组 | 否 |
find() |
查找第一个符合条件的元素 | 元素 / undefined |
否 |
findIndex() |
查找第一个符合条件元素的下标 | 下标 / -1 |
否 |
some() |
判断是否至少有一个满足条件 | boolean |
否 |
every() |
判断是否全部满足条件 | boolean |
否 |
includes() |
判断是否包含某个值 | boolean |
否 |
reduce() |
汇总、归并为一个结果 | 任意类型 | 否 |
slice() |
截取数组一部分 | 新数组 | 否 |
splice() |
删除 / 插入 / 替换元素 | 被删除元素组成的数组 | 是 |
concat() |
拼接数组 | 新数组 | 否 |
push() |
尾部添加元素 | 新长度 | 是 |
pop() |
删除尾部元素 | 被删除元素 | 是 |
shift() |
删除头部元素 | 被删除元素 | 是 |
unshift() |
头部添加元素 | 新长度 | 是 |
sort() |
排序 | 原数组 | 是 |
reverse() |
反转数组 | 原数组 | 是 |
join() |
拼接为字符串 | 字符串 | 否 |
flat() |
拍平数组 | 新数组 | 否 |
flatMap() |
映射后拍平一层 | 新数组 | 否 |
按功能分类理解数组方法
数组方法虽然多,但本质上可以按功能分成几类:
- 遍历类
- 判断类
- 查找类
- 筛选 / 转换类
- 归并统计类
- 截取 / 拼接类
- 增删类
- 排序类
- 字符串转换类
这样记,比死记单个 API 容易得多。
遍历类方法
forEach()
forEach 用来遍历数组中的每一项,并执行操作。
js
const arr = [1, 2, 3];
arr.forEach((item, index, array) => {
console.log(item, index, array);
});

参数说明
forEach 回调最多接收 3 个参数:
item:当前元素index:当前下标array:原数组本身
特点
- 用于"逐个处理"
- 没有返回新数组
- 常用于打印、做副作用操作、修改外部状态
注意点
很多人会把 forEach 和 map 混用,但其实两者区别很大:
forEach:更偏向"做事"map:更偏向"产出新数组"
判断类方法
some()
判断数组中是否至少有一个元素满足条件。
js
const arr = [1, 3, 5, 8];
const result = arr.some((item) => item % 2 === 0);
console.log(result); // true

适合场景:
- 是否存在未完成任务
- 是否存在未成年人
- 是否有一个用户满足某条件
every()
判断数组中是否所有元素都满足条件。
js
const arr = [2, 4, 6, 8];
const result = arr.every((item) => item % 2 === 0);
console.log(result); // true

适合场景:
- 检查一组数据是否全部合法
- 判断多个异步结果是否都准备好了
- 表单字段是否都已填写
includes()
判断数组中是否包含某个值。
js
const arr = ['apple', 'banana', 'orange'];
console.log(arr.includes('banana')); // true
console.log(arr.includes('grape')); // false

适合查找基本类型值,比如:
- 某权限是否存在
- 某状态是否在允许列表中
查找类方法
find()
返回第一个满足条件的元素。
js
const arr = [1, 3, 5, 8, 10];
const result = arr.find((item) => item % 2 === 0);
console.log(result); // 8

找不到时返回 undefined。
findIndex()
返回第一个满足条件元素的下标。
js
const arr = [10, 20, 30, 40];
const index = arr.findIndex((item) => item === 30);
console.log(index); // 2
找不到时返回 -1。
筛选与转换类方法
这一组是最常用、也最值得重点掌握的。
filter()
筛选出所有满足条件的元素,组成一个新数组。
js
const arr = [1, 2, 3, 4, 5, 6];
const evenNumbers = arr.filter((item) => item % 2 === 0);
console.log(evenNumbers); // [2, 4, 6]
特点
- 返回新数组
- 不修改原数组
- 可以筛出多个元素
map()
把数组中每个元素映射成一个新值,最后组成新数组。
js
const arr = [1, 2, 3];
const result = arr.map((item) => item * 2);
console.log(result); // [2, 4, 6]
适合场景
- 提取对象某个字段
- 数据格式转换
- 列表渲染前预处理
例如:
js
const users = [
{ id: 1, name: 'Tom' },
{ id: 2, name: 'Jerry' }
];
const names = users.map((user) => user.name);
console.log(names); // ['Tom', 'Jerry']
flat()
把嵌套数组拍平。
js
const arr = [1, [2, 3], [4, 5]];
console.log(arr.flat()); // [1, 2, 3, 4, 5]
多层嵌套时可以指定层数:
js
const arr = [1, [2, [3, 4]]];
console.log(arr.flat(2)); // [1, 2, 3, 4]
flatMap()
相当于 map + flat(1)。
js
const arr = [1, 2, 3];
const result = arr.flatMap((item) => [item, item * 10]);
console.log(result); // [1, 10, 2, 20, 3, 30]
归并统计类方法
reduce()
reduce 用来把整个数组归并成一个结果。
求和
js
const arr = [1, 2, 3, 4];
const sum = arr.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 10
统计次数
js
const arr = ['a', 'b', 'a', 'c', 'a'];
const countMap = arr.reduce((acc, cur) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc;
}, {});
console.log(countMap); // { a: 3, b: 1, c: 1 }
数组转对象
js
const users = [
{ id: 1, name: 'Tom' },
{ id: 2, name: 'Jerry' }
];
const userMap = users.reduce((acc, user) => {
acc[user.id] = user;
return acc;
}, {});
console.log(userMap);
什么时候用 reduce
当你想把数组最终变成:
- 一个数字
- 一个对象
- 一个布尔值
- 一个复杂结果
都可以考虑 reduce。
截取与拼接类方法
slice()
截取数组的一部分,不修改原数组。
js
const arr = [1, 2, 3, 4, 5];
console.log(arr.slice(1, 4)); // [2, 3, 4]
特点:
- 左闭右开
- 返回新数组
- 常用于复制部分数组
concat()
拼接数组,返回新数组。
js
const arr1 = [1, 2];
const arr2 = [3, 4];
const result = arr1.concat(arr2);
console.log(result); // [1, 2, 3, 4]
splice()
splice 很重要,它可以删除、插入、替换元素,并且会修改原数组。
删除元素
js
const arr = [1, 2, 3, 4];
arr.splice(1, 2);
console.log(arr); // [1, 4]
插入元素
js
const arr = [1, 2, 3];
arr.splice(1, 0, 'a', 'b');
console.log(arr); // [1, 'a', 'b', 2, 3]
替换元素
js
const arr = [1, 2, 3];
arr.splice(1, 1, 99);
console.log(arr); // [1, 99, 3]
增删类方法
push()
在尾部添加元素。
js
const arr = [1, 2];
arr.push(3);
console.log(arr); // [1, 2, 3]
pop()
删除最后一个元素。
js
const arr = [1, 2, 3];
arr.pop();
console.log(arr); // [1, 2]
unshift()
在头部添加元素。
js
const arr = [2, 3];
arr.unshift(1);
console.log(arr); // [1, 2, 3]
shift()
删除第一个元素。
js
const arr = [1, 2, 3];
arr.shift();
console.log(arr); // [2, 3]
排序类方法
sort()
sort 用于排序,但默认按字符串字典序排序。
js
const arr = [10, 2, 5];
arr.sort();
console.log(arr); // 结果可能不是你想要的数字顺序
数字排序时,通常这样写:
升序
js
const arr = [5, 2, 8, 1];
arr.sort((a, b) => a - b);
console.log(arr); // [1, 2, 5, 8]
降序
js
const arr = [5, 2, 8, 1];
arr.sort((a, b) => b - a);
console.log(arr); // [8, 5, 2, 1]
a - b 是什么意思
它不是随便减一下,而是比较函数的返回值:
- 返回负数:
a排前面 - 返回正数:
b排前面 - 返回 0:两者相等
所以:
js
(a, b) => a - b
本质就是让较小的数排前面。
reverse()
反转数组顺序。
js
const arr = [1, 2, 3];
arr.reverse();
console.log(arr); // [3, 2, 1]
转字符串类方法
join()
用指定分隔符把数组拼接成字符串。
js
const arr = ['a', 'b', 'c'];
console.log(arr.join('-')); // a-b-c
综合示例
假设有这样一组用户数据:
js
const users = [
{ id: 1, name: 'Tom', age: 16, active: true },
{ id: 2, name: 'Jerry', age: 20, active: false },
{ id: 3, name: 'Alice', age: 25, active: true },
{ id: 4, name: 'Bob', age: 17, active: true }
];
筛选成年人
js
const adults = users.filter((user) => user.age >= 18);
console.log(adults);
取出成年人姓名
js
const adultNames = users
.filter((user) => user.age >= 18)
.map((user) => user.name);
console.log(adultNames); // ['Jerry', 'Alice']
找到第一个未激活用户
js
const inactiveUser = users.find((user) => !user.active);
console.log(inactiveUser);
判断是否有未成年人
js
const hasMinor = users.some((user) => user.age < 18);
console.log(hasMinor); // true
判断是否全部激活
js
const allActive = users.every((user) => user.active);
console.log(allActive); // false
统计总年龄
js
const totalAge = users.reduce((sum, user) => sum + user.age, 0);
console.log(totalAge);
练习题
最后给几个很适合练手的小题目。
题目:找出所有偶数
已知:
js
const arr = [1, 2, 3, 4, 5, 6];
要求:返回所有偶数组成的新数组。
提示:用 filter
题目:把每个数字乘以 10
已知:
js
const arr = [1, 2, 3, 4];
要求:生成一个新数组 [10, 20, 30, 40]
提示:用 map
题目:判断是否存在大于 100 的数
已知:
js
const arr = [12, 45, 88, 120, 3];
要求:返回布尔值。
提示:用 some
题目:判断是否全部为正数
已知:
js
const arr = [1, 2, 3, 4, 5];
要求:返回布尔值。
提示:用 every
题目:找到第一个年龄大于等于 18 的用户
已知:
js
const users = [
{ name: 'Tom', age: 16 },
{ name: 'Jerry', age: 20 },
{ name: 'Alice', age: 17 }
];
要求:返回符合条件的第一个对象。
提示:用 find
题目:计算数组总和
已知:
js
const arr = [10, 20, 30, 40];
要求:求总和 100
提示:用 reduce
题目:按年龄升序排序
已知:
js
const users = [
{ name: 'Tom', age: 25 },
{ name: 'Jerry', age: 18 },
{ name: 'Alice', age: 30 }
];
要求:按 age 从小到大排序。
提示:用 sort((a, b) => a.age - b.age)
总结
JavaScript 的数组方法虽然看起来很多,但它们做的事情其实并不复杂,本质上无非就是:
- 遍历
- 判断
- 查找
- 筛选
- 转换
- 统计
- 排序
- 增删改
学习数组方法时,不要一上来就死记所有 API,而是先问自己一句:
我现在到底是想遍历、筛选、查找,还是汇总?
只要这个问题想清楚,对应的方法通常就很自然了。
对于初学者来说,最值得优先掌握的 6 个方法是:
mapfilterfindsomeeveryreduce
把这几个吃透,日常开发中大多数数组操作你都能写得很顺手。