处理数据是前端每天的工作,数组高阶方法就是那把"瑞士军刀"。学会 map、filter、reduce,几行声明式代码就能替代一大坨 for 循环,更短、更不易错、更好读。本文用真实场景逐个击破。
1. 为什么需要高阶方法
高阶方法把"遍历"封装起来,你只需关心"每个元素怎么处理"。先看对比:
const prices = [10, 20, 30];
// 高阶写法:一行替代 for + push
const doubled = prices.map((p) => p * 2);
console.log(doubled); // [20, 40, 60]
2. forEach 与 map:遍历与变换
const users = [
{ name: "Ada", age: 18 },
{ name: "Bob", age: 25 },
{ name: "Cici", age: 30 },
];
// forEach:只遍历,不返回新数组
users.forEach((u) => console.log(u.name));
// map:返回"每个元素变换后"组成的新数组
const names = users.map((u) => u.name);
要点:forEach 返回 undefined,map 返回等长新数组。
3. filter 与 find:筛选
// filter:所有满足条件的元素
const adults = users.filter((u) => u.age >= 18);
// find:第一个满足条件的元素(找不到返回 undefined)
const bob = users.find((u) => u.name === "Bob");
console.log(bob.age); // 25
4. some 与 every:存在性判断
// 有一个满足即 true
const hasTeen = users.some((u) => u.age < 18);
console.log(hasTeen); // false(最小 18)
// 全部满足才 true
const allNamed = users.every((u) => u.name.length > 0);
console.log(allNamed); // true
表单校验里常用:"至少填一项"用 some,"全部合法"用 every。
5. reduce:汇总一切
const orders = [
{ item: "键盘", qty: 2, price: 399 },
{ item: "鼠标", qty: 1, price: 99 },
];
// 总价:第二个参数 0 是初始值
const total = orders.reduce((sum, o) => sum + o.qty * o.price, 0);
console.log(total); // 897
// 数组去重
const nums = [1, 2, 2, 3, 3, 3];
const unique = nums.reduce((acc, n) => {
if (!acc.includes(n)) acc.push(n);
return acc;
}, []);
6. 链式调用:数据处理流水线
const products = [
{ name: "键盘", price: 399, stock: 5 },
{ name: "显示器", price: 1299, stock: 0 },
{ name: "鼠标", price: 99, stock: 20 },
{ name: "耳机", price: 299, stock: 3 },
];
// 需求:有货的商品,按价格降序,只要名字
const result = products
.filter((p) => p.stock > 0)
.sort((a, b) => b.price - a.price)
.map((p) => p.name);
console.log(result); // ["键盘", "耳机", "鼠标"]
每一步都返回新数组,像流水线一样清晰。注意 sort 会原地修改原数组,需要保留原数据时先 [...arr] 拷贝一份。
7. 方法对比速查表
| 方法 | 返回 | 是否改原数组 | 典型用途 |
|---|---|---|---|
| forEach | undefined | 否 | 遍历副作用 |
| map | 等长新数组 | 否 | 数据变换 |
| filter | 子集新数组 | 否 | 筛选 |
| find | 单个元素 | 否 | 查找 |
| reduce | 任意值 | 否 | 汇总、去重、分组 |
| sort | 原数组(原地) | 是 | 排序 |
💡 把"用 for 循环写"的习惯换成"先想用哪个方法":变换用 map,筛选用 filter,汇总用 reduce。坚持一周,你的代码会明显变清爽。