第 13 周总结:对象扩展与 Set/Map — 数据结构版图补齐
蜗牛往上爬 · 前端工业可视化学习笔记 第 13 周总结
本周完成了数据结构的升级:对象的新写法(简写、可选链、空值合并)让代码更安全优雅;Set 和 Map 补齐了"唯一集合"和"任意键值对"两块版图。综合实战"设备状态管理器"把本周知识融会贯通。
目录
一、本周学了什么
知识图谱
对象扩展与 Set/Map
├── 对象扩展
│ ├── 属性简写 { id } / 方法简写 fn() {}
│ ├── 计算属性名 [key]
│ ├── Object.keys / values / entries(遍历三件套)
│ ├── Object.assign / {...a, ...b}(合并,后覆盖前)
│ ├── 可选链 ?.(深层安全访问)
│ └── 空值合并 ??(只兜底 null/undefined)
│
├── Set(唯一值集合)
│ ├── add / has / delete / size / clear
│ ├── 去重:[...new Set(arr)]
│ ├── 集合运算:并 / 交 / 差
│ └── has 是 O(1)(比 includes 快)
│
├── Map(任意类型键的键值对)
│ ├── set / get / has / delete / size
│ ├── 对象可以做键
│ ├── 遍历:for...of 解构 / keys / values
│ ├── 互转:Object.entries / fromEntries
│ └── 词频统计模板
│
└── 选型决策
├── 有序一组 → 数组
├── 描述实体 → 对象
├── 不重复/判存在 → Set
└── 动态键/计数 → Map
二、核心知识速记
三条铁律
||会误伤 0 和 “”——有效值兜底用??去重一行:
[...new Set(arr)]大量数据频繁判断存在——用 Set.has,不用 arr.includes
高频写法
// 安全访问 + 兜底(黄金组合)
const temp = api?.data?.device?.temp ?? 0;
// 合并配置(默认 + 用户)
const config = { ...defaults, ...userOptions };
// 对象遍历(entries + 解构)
for (const [key, value] of Object.entries(obj)) {}
// 去重
const unique = [...new Set(arr)];
// 词频统计
counter.set(key, (counter.get(key) || 0) + 1);
// Map → 对象
Object.fromEntries(map);
四大结构选型表
在工业可视化里的应用场景
三、本周踩过的坑
坑点 1:用 || 兜底把 0 干掉了
// ❌ 温度 0 是有效值,却被替换成 25
function setTemp(value) {
this.temp = value || 25; // 0 → 25,错!
}
// ✅ 用 ?? 只兜底 null/undefined
function setTemp(value) {
this.temp = value ?? 25; // 0 → 0,正确
}
坑点 2:对象展开是浅拷贝
// ❌ 嵌套对象仍共享引用
const base = { chart: { width: 400 } };
const config = { ...base };
config.chart.width = 600;
console.log(base.chart.width); // 600 ⚠ 被改了!
// ✅ 深拷贝(简单场景)
const config2 = JSON.parse(JSON.stringify(base));
// 或对嵌套层再展开
const config3 = { ...base, chart: { ...base.chart } };
坑点 3:Map 的 get 链上直接取属性
// ❌ 设备不存在时,get 返回 undefined,取属性报错
console.log(devices.get("XXX").temp); // TypeError
// ✅ 先判断或用可选链
const d = devices.get("XXX");
console.log(d?.temp); // undefined(安全)
console.log(d ? d.temp : 0); // 0
坑点 4:Set 存对象"去重"失效
// ❌ 对象引用不同,Set 认为是不同值
const set = new Set();
set.add({ id: "A" });
set.add({ id: "A" }); // 两个不同对象!
console.log(set.size); // 2 ⚠
// ✅ 存原始值(字符串/数字)才能去重
const ids = new Set();
ids.add("A");
ids.add("A");
console.log(ids.size); // 1 ✅
坑点 5:Object.fromEntries 用在非字符串键的 Map 上
// Map 的键是对象时,转对象会出问题
const map = new Map([[{ id: 1 }, "data"]]);
// Object.fromEntries(map) // 键会变成 "[object Object]"
// ✅ 只有字符串键的 Map 才适合转对象
const strMap = new Map([["a", 1], ["b", 2]]);
Object.fromEntries(strMap); // { a: 1, b: 2 } ✅
四、自测清单
[ ] 属性简写和方法简写的写法?
[ ] 计算属性名怎么写?什么场景用?
[ ] Object.entries 返回什么?怎么配合 for…of?
[ ] Object.assign 合并时谁覆盖谁?
[ ] 可选链 ?. 解决什么问题?
[ ] || 和 ?? 的区别?什么时候必须用 ???
[ ] Set 怎么创建?怎么去重数组?
[ ] Set 的 has 和数组 includes 谁快?为什么?
[ ] 怎么求两个 Set 的交集/差集?
[ ] Map 和对象的核心区别?
[ ] Map 怎么遍历?keys/values 怎么用?
[ ] 对象和 Map 怎么互转?
[ ] 词频统计的模板代码怎么写?
[ ] 四大数据结构各自的适用场景?
[ ] 为什么 Set 存对象去重会失效?
五、下周预告
第 14 周:异步编程(Promise / async await)— ES6 最重要的一战
异步是大屏的命脉——所有数据都来自接口请求。下周把 Promise 和 async/await 彻底吃透,就能写出真正的数据驱动页面。
🚀 第 13 周完成!数据结构版图补齐。下周迎战 ES6 最核心的异步编程——这是通往真实项目的必经之路!