JS 第7周笔记-数组方法(map&filter&reduce& find&some&every&includes)
本篇文章重点知识写下了 本篇文章重点知识写下了 本篇文章重点知识写下了
路线图阶段:第二阶段(现代 JavaScript 补全)第7周 性质:不是从零学,而是把第一阶段”用过但没吃透”的数组方法夯实,并补上没用过的 reduce 及其他高频方法 核心:这一族方法是同一个骨架 —— 遍历数组 + 回调函数,区别只在”怎么处理回调的返回值”
0. 统一心智模型
数组.方法((item) => ...)
// └────┬────┘
// 回调函数,几乎都不能少(includes 例外)
- map / filter / reduce / find / some / every 第一个参数都是回调函数。
- 回调里
item是参数,方法遍历时把每一项传进来。 - ⚠️ 不能直接写条件
方法(item.age > 30)—— item 未定义会报错,且方法要的是函数不是值。 必须包成方法((item) => item.age > 30)。
1. map:加工每一项
[1, 2, 3].map((n) => n * 2) // → [2, 4, 6]
- 回调返回值 → 放进新数组的对应位置。
- 一对一变换:输出数组和原数组等长。
2. filter:留下符合条件的
cart.filter((item) => item.price > 200)
- 回调返回 true/false → true 的项保留,false 的去掉。
- 输出数组长度 ≤ 原数组(全通过则等长,筛掉则变短)。
3. reduce:把数组”滚雪球”成一个值(本周重点)
map/filter 输出还是数组;reduce 把整个数组收拢成一个单一的值(数字、字符串、对象……)。
const sum = numbers.reduce((acc, current) => {
return acc + current;
}, 0);
// ↑ 回调 ↑ 初始值
两个关键概念
- acc(accumulator 累加器):到目前为止”累积的结果”(雪球)。
- 初始值(最后那个参数):雪球的起点。
- 每轮回调的返回值 → 成为下一轮的 acc。
- ⚠️ 每轮必须
return acc,否则下一轮雪球丢失。
雪球过程(求和 [1,2,3,4] 初始值 0)
起点 acc=0 → +1=1 → +2=3 → +3=6 → +4=10 → 返回 10
初始值类型 = 最终结果类型(通用判断法)
求和 → 结果是数字 → 初始值 0
拼字符 → 结果是字符串 → 初始值 ""
分组统计 → 结果是对象 → 初始值 {}
进阶:汇总成对象(分组计数)
const photos = [{author:"Kevin"},{author:"Aki"},{author:"Kevin"}];
const counts = photos.reduce((acc, item) => {
acc[item.author] = (acc[item.author] || 0) + 1;
return acc;
}, {});
// → { Kevin: 2, Aki: 1 }
要点:
- acc 全程是对象(初始值
{})。 acc[item.author] = ...:给不存在的 key 赋值时,JS 自动把该 key 加进对象 —— 作者名就是这样”长”进 acc 的。(acc[item.author] || 0):第一次遇到时 acc 里没有该键(undefined),|| 0兜底成 0,避免undefined + 1 = NaN。值 || 默认值是 JS 极常用写法:左边是假值(undefined/0/"")就用右边。
⚠️ 反复栽的同一个坑:item.xxx vs acc[…]
item.author → 当前项的原始数据(作者是谁,如 "Kevin")
acc[item.author] → 累积到现在的结果(这个作者数到几了)
- 求和时错写
acc + item(item 是对象)→ 应为acc + item.price。 - 计数时错写
(item.author || 0)(取到作者名字符串)→ 应为(acc[item.author] || 0)。 - 记牢:item 是原始数据,acc 是累积结果,别混。
4. 方括号取值(bracket notation)
reduce 计数题用到,单独记一下。
const obj = { Kevin: 3 };
obj.Kevin // 点号:key 写死
obj["Kevin"] // 方括号:等价
const author = "Kevin";
obj.author // ❌ 字面找名叫 "author" 的键 → undefined
obj[author] // ✅ author 是变量,先求值成 "Kevin",再取 → 3
- key 是动态变量时,必须用方括号(点号只能写死的属性名)。
- 取值、赋值都能用:
acc[item.author] = ...。
5. find:找出第一个符合的项
const user = users.find((item) => item.age > 30);
- 返回单个项本身(不是数组),找不到返回
undefined。 - 对比 filter:
filter → 返回数组 [所有符合的]
find → 返回单个 {第一个符合的} / undefined
- 高频场景:按唯一 id 找一条数据(点击列表项 → 根据 id 找完整对象)。
6. some / every:返回 true/false 的判断题
cart.some((item) => item.price > 200) // 有没有"任意一个"符合? 一个符合就 true
cart.every((item) => item.price > 200) // 是不是"每一个"都符合? 一个不符合就 false
some→ “有没有任意一个?”every→ “是不是全部?”(有一个反例就 false)- 场景:some → “有没有缺货商品?“;every → “表单是不是每项都填了?“
7. includes:数组含不含某个值
["react", "css"].includes("react") // → true
- 直接比对值,不需要回调(这一族里唯一不要回调的)。
- 只适合简单值(字符串、数字)。要按条件找对象,用 some / find。
- 字符串也有 includes(第5周用过:
author.includes(query))。
速查表:想要什么 → 用哪个
| 你想要… | 用 | 返回 | 要回调? |
|---|---|---|---|
| 加工每一项 | map | 等长新数组 | 是 |
| 留下符合的(多个) | filter | 新数组(可能短) | 是 |
| 找第一个符合的 | find | 单个项 / undefined | 是 |
| 汇总成一个值 | reduce | 任意(数字/对象…) | 是 |
| 有没有任意一个符合 | some | true / false | 是 |
| 是不是全部符合 | every | true / false | 是 |
| 数组含不含某个值 | includes | true / false | 否 |
第7周验收
- 理解 map/filter/reduce 是同一骨架,区别在”如何处理回调返回值”
- 会用 reduce 汇总成数字 和 汇总成对象(分组计数)
- 懂方括号动态取值 acc[item.author]
- 分清 item(原始数据) vs acc(累积结果)
- 会按需求选 find / some / every / includes
下一步(第8周预告)
- 现代 JS 继续:解构(destructuring)深入、展开运算符、async/await + fetch 系统梳理
- 这些你第一阶段都用过,第8周把它们讲透
- 之后第9-10周进入 TypeScript