ES6 数组扩展
数组是 JS 里最常用的数据结构之一,ES6 以及后续版本补充了一大批实用的数组方法。
这篇只挑日常开发最高频、最实用的:forEach、map、filter、reduce、find、findIndex、includes、some、every、flat 和 Array.from()。
掌握这些,处理数据流的效率会有质的提升。
遍历与处理
这一组方法都会遍历数组的每个元素,但用途不同:forEach 只负责”做事”,map 负责”加工出新数组”,filter 负责”按条件挑出”。
forEach:遍历执行
对每个元素执行一段代码,无返回值:
// 示例
const list = ['苹果', '香蕉', '橘子'];
list.forEach(function (item, index) {
console.log(index, item);
});
// 0 苹果
// 1 香蕉
// 2 橘子
方便和箭头函数一起用:
// 示例
list.forEach((item) => console.log(item));
map:映射,生成新数组
把每个元素经过处理后,翻一个新数组返回。原数组不变:
// 示例
const nums = [1, 2, 3];
const doubles = nums.map((n) => n * 2);
console.log(doubles); // [2, 4, 6]
常用于把一组对象「抽字段」出来:
// 示例
const users = [
{ name: '张三', age: 20 },
{ name: '李四', age: 30 },
];
const names = users.map((u) => u.name);
console.log(names); // ['张三', '李四']
filter:筛选,留下满足条件的
返回满足条件的元素组成新数组,找不到则返回空数组:
// 示例
const nums = [1, 2, 3, 4, 5];
const big = nums.filter((n) => n > 3);
console.log(big); // [4, 5]
reduce:聚合成一个值
把整个数组”折叠”成一个结果(求和、统计等)。回调第一个参数是上一次的结果(累加器),第二个是当前元素:
// 示例:累加求和
const nums = [1, 2, 3, 4];
const total = nums.reduce((sum, n) => sum + n, 0);
console.log(total); // 10
最后那个 0 是初始值,从它开始累加。不传初始值时,会自动拿第一个元素当初始值(容易踩坑,建议显式传入)。
// 示例:统计对象数组的金额
const orders = [{ price: 10 }, { price: 20 }, { price: 30 }];
const sum = orders.reduce((total, o) => total + o.price, 0);
console.log(sum); // 60
日常常和 map/filter 连用:先筛选 → 再加工 → 最后汇总。
查找元素
这一组方法用于在数组中”找东西”,都返回单个结果,不做整组加工。
find:找到第一个符合条件的
返回第一个满足条件的元素,找不到返回 undefined:
// 示例
const nums = [1, 2, 3, 4, 5];
const first = nums.find((n) => n > 2);
console.log(first); // 3
findIndex:找到符合条件的下标
返回第一个满足条件的元素下标,找不到返回 -1:
// 示例
const nums = [10, 20, 30];
console.log(nums.findIndex((n) => n === 20)); // 1
console.log(nums.findIndex((n) => n === 99)); // -1
includes:是否包含某个元素
返回布尔值,判断数组中是否包含指定值:
// 示例
const arr = ['a', 'b', 'c'];
console.log(arr.includes('b')); // true
console.log(arr.includes('z')); // false
条件判定
这一组方法把整个数组当成一个整体”打分数”,返回布尔值。
| 方法 | 含义 | 结果 |
|---|---|---|
some(回调) |
只要有一个满足就返回 true |
布尔 |
every(回调) |
全部满足才返回 true |
布尔 |
// 示例
const nums = [1, 3, 5];
console.log(nums.some((n) => n > 4)); // true —— 有 5 满足
console.log(nums.every((n) => n > 0)); // true —— 全大于 0
结构转换
这一组方法负责改变数组的”形态”,不遍历逻辑处理,而是转换结构。
flat:扁平化嵌套数组
把嵌套的数组”摊平”一层(或指定层数):
// 示例
const nested = [1, [2, 3], [4, [5, 6]]];
console.log(nested.flat()); // [1, 2, 3, 4, [5, 6]] —— 默认只摊平一层
console.log(nested.flat(2)); // [1, 2, 3, 4, 5, 6] —— 摊两层
console.log(nested.flat(Infinity)); // 全摊平
Array.from():把类数组转换为数组
把”长得像数组但不是数组”的东西(如 arguments、NodeList、Set)转成真正的数组,就能使用上面的各种方法:
// 示例
const str = 'abc';
console.log(Array.from(str)); // ['a', 'b', 'c'] 字符串 -> 数组
const fake = { 0: 'x', length: 1 };
console.log(Array.from(fake)); // ['x'] 类数组 -> 数组
对比记忆:Array.from() 是把”伪数组”变成数组;Array.isArray(x) 是判断 x 是否数组,两者都很有用。
最后
| 方法 | 作用 | 返回值 |
|---|---|---|
forEach |
遍历 | 无 |
map |
映射转换 | 新数组 |
filter |
按条件筛选 | 新数组 |
reduce |
聚合成一个值 | 任意值 |
find |
找第一个符合的 | 元素 or undefined |
findIndex |
找第一个符合条件的下标 | 下标 or -1 |
includes |
是否包含某值 | 布尔 |
some / every |
是否存在 / 是否全部符合 | 布尔 |
flat |
扁平化嵌套 | 新数组 |
Array.from |
类数组转真数组 | 数组 |
这些方法相当于是数组的精英工具库,掌握后你的数据处理功力会上一个台阶。日常写代码时它们出现的频率最高,值得反复练习。