05对象与数组基础
JavaScript 最常用的两个数据结构:对象 { key: value } 和
数组 [item, item]。
对象描述「一个东西有什么属性」,数组描述「一组有序的东西」。
本课一次讲清 CRUD + 常用方法,让你能处理真实数据。
一、对象字面量与 CRUD
对象用 { } 字面量创建,是一组「键值对」的集合。
键也叫属性,值可以是任何类型——数字、字符串、数组、函数都行。
| 动作 | 语法 | 说明 |
|---|---|---|
| 创建 | const o = { k: v } | 字面量最直观;方括号允许动态键 |
| 读 | o.k / o['k'] | 键含空格或连字符时必须用方括号 |
| 增 / 改 | o.k = v | 不存在就加,存在就覆盖 |
| 查 | 'k' in o | 包含继承属性;想只看自身用 hasOwnProperty |
| 删 | delete o.k | 返回布尔值;数组的 delete 会留下空位 |
in 检查——把 user.name 改成 '后端' 看日志变化o[key]。二、对象解构与展开
解构是从对象里「批量取出」属性的语法糖; 展开是「合并对象」的语法糖。两兄弟一进一出,处理数据时天天见。
{ city = '未知' } 只在原对象没有这个键时生效;
如果原值是 null,默认值不生效(null 是合法值)。extra = 999 也合进去看日志{ ...obj }
只拷贝一层。对象里嵌套的对象 / 数组,仍然是引用——
改内层会同时影响原对象和副本。深拷贝得用 structuredClone()。三、对象方法与 this
对象里的函数叫「方法」,方法里 this 默认指向「调用它的那个对象」。
用好 this,方法就能感知自己属于谁。
| 方法 | 返回 | 用途 |
|---|---|---|
Object.keys(o) | 键数组 ['name','age'] | 需要键名列表时 |
Object.values(o) | 值数组 ['前端',3] | 需要值列表时 |
Object.entries(o) | 二维数组 [[k,v],...] | 配合 for...of / Map |
Object.assign(a, b) | 合并后的 a | 把 b 的属性塞给 a,会修改 a |
{ ...a, ...b } | 新对象 | 展开更直观;不修改任何原对象 |
greet(),三种遍历把对象「翻个底朝天」——把 role 也加进去再看一遍arrow: () => ...,
里的 this 会指到外层(通常是 window),而不是对象本身。要用 this 就写普通方法。四、数组创建与访问
数组是有序集合,用 [ ] 字面量最直观。
元素按下标(从 0 开始)排列,length 自动跟着增减。
| 动作 | 方法 | 是否修改原数组 |
|---|---|---|
| 末尾增 | arr.push(x) | ✓ 修改,返回新长度 |
| 末尾删 | arr.pop() | ✓ 修改,返回被删元素 |
| 开头增 | arr.unshift(x) | ✓ 修改,返回新长度 |
| 开头删 | arr.shift() | ✓ 修改,返回被删元素 |
| 查位置 | arr.indexOf(x) | ✗ 不修改,找不到返回 -1 |
| 判断包含 | arr.includes(x) | ✗ 不修改,返回布尔 |
五、数组常用方法(11 件套)
数组方法多到记不住,但这 11 个覆盖 90% 日常场景。 关键看「是否修改原数组」——这是面试最爱问的点。
| 方法 | 作用 | 改原数组? | 返回 |
|---|---|---|---|
push(x) | 末尾加 | ✓ | 新长度 |
pop() | 末尾删 | ✓ | 被删元素 |
shift() | 开头删 | ✓ | 被删元素 |
unshift(x) | 开头加 | ✓ | 新长度 |
splice(i, n, ...) | 从 i 删 n 个,可插入新元素 | ✓ | 被删元素数组 |
slice(s, e) | 截取 [s, e) | ✗ | 新数组 |
concat(b) | 拼接 | ✗ | 新数组 |
indexOf(x) | 找下标 | ✗ | 下标 / -1 |
includes(x) | 判断包含 | ✗ | 布尔 |
join('-') | 数组 → 字符串 | ✗ | 字符串 |
reverse() | 反转 | ✓ | 反转后的原数组 |
splice 是修改原数组的万能手术刀;
slice 是不修改的纯截取。
想保留原数组,请用 slice。六、数组高阶函数:map / filter / reduce / find / some / every
高阶函数:接收函数当参数的函数。这六兄弟是处理数组的「瑞士军刀」, 不修改原数组,返回一个新值(reduce 例外,输出任意类型)。
| 函数 | 作用 | 回调签名 | 返回 |
|---|---|---|---|
map | 每个元素变换 | (item) => newItem | 新数组 |
filter | 留下满足条件的 | (item) => bool | 新数组 |
reduce | 把数组「折」成一个值 | (acc, cur) => newAcc | 任意(数字 / 对象 / 字符串…) |
find | 找第一个匹配 | (item) => bool | 元素 / undefined |
some | 至少一个满足 | (item) => bool | 布尔 |
every | 全都满足 | (item) => bool | 布尔 |
七、对象数组实战 + 数组解构
真实项目里 90% 的数据都是「对象数组」——
用户列表、商品列表、成绩单……都是 [{...}, {...}, ...] 的形状。
把前面的方法串起来,就能处理任何列表数据。
八、本章小结
- 对象
{ k: v }描述一个东西的属性;数组[ ]描述一组有序的东西——前者按键访问,后者按下标访问。 - 对象 CRUD:点 / 方括号读,
o.k = v增改,'k' in o查,delete o.k删。 - 解构拆出属性,展开
...合并 / 克隆对象;展开只浅拷贝一层。 - 对象方法里
this默认指向调用者;箭头函数没有自己的 this,别在对象方法里用。 - 数组 11 件套看是否修改原数组:push / pop / shift / unshift / splice / reverse 改;slice / concat / indexOf / includes / join 不改。
- 六高阶函数 都不修改原数组:map 变、filter 筛、reduce 折、find 找、some / every 判断。
- 实战都是对象数组
[{...}, ...]:map 提取、filter 筛选、reduce 汇总,串起来就是「列表页」的全部逻辑。
title 和 done 两个字段,至少 5 条),
①用 filter 取出已完成项;
②用 map 提取标题数组;
③用 reduce 统计已完成数量。
进阶:再用 { ...todo, done: true } 改写第一项的 done 为 true(不要直接赋值)。