Pixiv - KiraraShss
1896 字
9 分钟
数组方法总结
欢迎来到我的博客!
使用 Markdown 格式编写。
今天学到了什么
- 数组方法总结
数组方法总结
这几个数组迭代方法在底层设计上非常相似,它们的参数结构几乎是一致的。
我们把它们分为两类来详细整理:普通迭代方法(forEach, map, filter, find, every)和 归并方法(reduce)。
第一类:普通迭代方法
这五个方法:forEach、map、filter、find、every,它们接收的参数格式是完全一样的。
通用语法:
arr.方法名(function(item, index, array) { // 函数体}, thisArg)参数详解:
callbackFn(回调函数):数组中每个元素都会执行一次这个函数。它接收 3 个参数:item(必须):当前正在处理的元素(当前值)。index(可选):当前正在处理的元素的索引(下标,从 0 开始)。array(可选):调用该方法的数组本身(原数组)。
thisArg(可选):执行回调函数时,用作this的值。(在箭头函数中无效,现代开发中极少使用,通常忽略)。
1. forEach (纯遍历)
- 作用:对数组的每个元素执行一次给定的函数。
- 返回值:
undefined。 - 注意:无法使用
break或continue中断循环(除非抛出异常)。
const arr = ['a', 'b', 'c'];arr.forEach((item, index, array) => { console.log(`元素: ${item}, 索引: ${index}, 原数组: ${array}`);});// 输出:// 元素: a, 索引: 0, 原数组: a,b,c// 元素: b, 索引: 1, 原数组: a,b,c// 元素: c, 索引: 2, 原数组: a,b,c2. map (映射)
- 作用:创建一个新数组,其结果是该数组中的每个元素都调用一次提供的函数后的返回值。
- 返回值:一个新数组。
- 注意:回调函数中必须有
return,否则新数组里的元素都是undefined。
const arr = [1, 2, 3];const newArr = arr.map((item, index) => { return item * 2 + index; // 当前值乘2,再加上索引});console.log(newArr); // [2, 5, 8]3. filter (筛选)
- 作用:创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
- 返回值:一个新数组。如果没有任何元素通过测试,则返回空数组
[]。 - 注意:回调函数必须返回一个布尔值(或能转换为布尔值的值)。返回
true的元素会被保留,false的会被丢弃。
const arr = [10, 20, 30, 40];const newArr = arr.filter((item, index) => { return item > 15 && index % 2 === 1; // 值大于15,且索引是奇数});console.log(newArr); // [20, 40]4. find (查找)
- 作用:返回数组中满足提供的测试函数的第一个元素的值。
- 返回值:找到的元素本身。如果找不到,返回
undefined。 - 注意:一旦找到符合条件的元素(回调返回
true),就会立即停止遍历,不会继续往下找。
const users = [ { id: 1, name: '张三' }, { id: 2, name: '李四' }, { id: 3, name: '王五' }];const target = users.find((item, index) => { return item.id === 2;});console.log(target); // { id: 2, name: '李四' }5. every (全员检测)
- 作用:测试一个数组内的所有元素是否都能通过某个指定函数的测试。
- 返回值:布尔值 (
true或false)。 - 注意:
- 如果回调函数对所有元素都返回
true,则结果为true。 - 只要遇到一个元素让回调返回
false,就会立即停止遍历,并返回false(一假即假)。 - 若对空数组调用,始终返回
true。
- 如果回调函数对所有元素都返回
const arr = [10, 20, 30];const isAllPositive = arr.every((item) => { return item > 0;});console.log(isAllPositive); // true第二类:归并方法 (reduce)
reduce 的参数结构与上面五个不同,因为它需要维护一个“累加器”(上一次计算的结果)。
语法:
arr.reduce(function(accumulator, currentValue, currentIndex, array) { // 函数体,必须 return 一个值作为下一次的 accumulator}, initialValue)参数详解:
callbackFn(回调函数):接收 4 个参数:accumulator(累加器,必须):上一次调用回调时返回的值。如果是第一次调用,它的值取决于是否提供了initialValue。currentValue(当前值,必须):数组中正在处理的元素。currentIndex(当前索引,可选):数组中正在处理的当前元素的索引。array(原数组,可选):调用reduce()的数组。
initialValue(初始值,强烈建议提供):作为第一次调用callback函数时accumulator的值。- 如果不提供初始值:
reduce会把数组的第一个元素作为初始的accumulator,并从第二个元素开始遍历(currentIndex从 1 开始)。如果数组为空且没有初始值,会报错。 - 如果提供初始值:
accumulator初始就是这个值,遍历从第一个元素开始(currentIndex从 0 开始)。
- 如果不提供初始值:
示例 1:求和 (最常见用法)
const arr = [1, 2, 3, 4];
// 提供初始值 0const sum = arr.reduce((acc, current) => { return acc + current;}, 0);
console.log(sum); // 10
/* 执行过程拆解:第一次:acc = 0 (初始值), current = 1, return 0 + 1 = 1第二次:acc = 1 (上次的return), current = 2, return 1 + 2 = 3第三次:acc = 3, current = 3, return 3 + 3 = 6第四次:acc = 6, current = 4, return 6 + 4 = 10最终结果:10*/示例 2:统计元素出现次数 (进阶用法)
const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
// 初始值提供一个空对象 {}const countedNames = names.reduce((allNames, name) => { if (name in allNames) { allNames[name]++; // 如果对象里有这个名字,次数 +1 } else { allNames[name] = 1; // 如果没有,初始化为 1 } return allNames; // 必须把对象 return 出去,供下一次循环使用}, {});
console.log(countedNames);// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }表 1:常用迭代方法速查表
| 方法 | 核心作用 | 返回值 | 是否改变原数组 | 能否中途停止 | 典型应用场景 |
|---|---|---|---|---|---|
| forEach | 纯执行 | undefined | 否 | ❌ 不能 | 简单的循环打印、操作 DOM |
| map | 加工/映射 | 新数组 (长度不变) | 否 | ❌ 不能 | 数据格式转换 (如对象数组转 ID 数组) |
| filter | 筛选/过滤 | 新数组 (长度 ≤ 原数组) | 否 | ❌ 不能 | 只要及格的分数、删除特定 ID 的数据 |
| find | 查找单个 | 元素本身 (没找到返 undefined) | 否 | ✅ 找到即停 | 找 ID 为 1001 的那个用户 |
| every | 全员检测 | 布尔值 (全对才 true) | 否 | ✅ 遇错即停 | 判断“全选”状态 |
| some | 部分检测 | 布尔值 (有一个能行就 true) | 否 | ✅ 遇对即停 | 判断是否至少有一个商品被选中 |
| reduce | 累计/归并 | 自定义 (数字/对象等) | 否 | ❌ 不能 | 求和、去重、统计次数 |
表 2:参数详解表 (Callback 写法)
绝大多数方法(forEach, map, filter, find, every, some)的参数完全一致,只有 reduce 比较特殊。
| 分类 | 语法结构 | 参数说明 (item: 当前项, index: 索引, arr: 原数组) |
|---|---|---|
| 通用类 (大多数) | arr.方法((item, index, arr) => { ... }) | 1. item (必选): 当前遍历到的元素2. index (可选): 当前元素的下标 (0, 1, …)3. arr (可选): 当前数组本身 |
| 累计类 (reduce) | arr.reduce((acc, item, index, arr) => { ... }, init) | 1. acc (必选): 累计器 (上一次回调的返回值)2. item (必选): 当前遍历到的元素3. index (可选): 当前索引4. arr (可选): 原数组--- init (可选推荐): 初始值 (作为第一次的 acc) |
💡 特别提醒 reduce 的参数陷阱:
- 如果不传
init(初始值):acc初始值 = 数组的第1个元素。item从数组的第2个元素开始遍历。index从 1 开始。
- 如果传了
init(初始值) (推荐做法):acc初始值 =init。item从数组的第1个元素开始遍历。index从 0 开始。
赞助支持
如果这篇文章对你有帮助,欢迎赞助支持!
最后更新于 2026-02-24,距今已过 24 天
部分内容可能已过时