为什么会有 map、weakmap 类型?
- 传统对象的局限性催生 Map
- 1. 键类型单一性
- 2. 有序性与迭代支持
- 3. 性能优化场景
- 内存管理需求催生 WeakMap
- 1.弱引用机制
- 2. 私有数据存储
- 3. 规避循环引用问题
- 总结
传统对象的局限性催生 Map
1. 键类型单一性
传统对象(Object
)的键只能是字符串或 Symbol
,无法直接使用对象、函数等复杂类型作为键名。而 Map 允许任意数据类型作为键(包括对象、函数等),解决了键类型受限的问题
。
// 传统对象键名被强制转为字符串 :ml-citation{ref="4" data="citationList"}
const objKey = { id: 1 };
const data = {};
data[objKey] = 'value'; // 键名实际存储为 "[object Object]"
console.log(data['[object Object]']); // 输出 "value"// Map 直接使用对象作为键 :ml-citation{ref="4,6" data="citationList"}
const map = new Map();
map.set(objKey, 'value');
console.log(map.get(objKey)); // 直接输出 "value"
2. 有序性与迭代支持
Map
保持键值对的插入顺序,支持通过 forEach、for...of
等方法遍历,且提供 size
属性快速获取键值对数量,弥补了传统对象无法保证顺序和统计大小的不足
。
const map = new Map();
map.set('a', 1).set('b', 2);
for (const [key, val] of map) {console.log(key, val); // 输出顺序:a 1 → b 2
}
3. 性能优化场景
在频繁增删键值对或需要大量非字符串键的场景下,Map 的性能优于传统对象(尤其在处理对象键时)。
内存管理需求催生 WeakMap
1.弱引用机制
WeakMap
的键必须是对象,且对键是弱引用(不阻止垃圾回收)。当键对象被外部代码释放后,WeakMap 会自动清理对应的键值对,避免内存泄漏。
2. 私有数据存储
WeakMap
适合存储与对象生命周期绑定的私有数据,例如 Vue3
中管理组件响应式数据。
// 模拟 Vue3 响应式系统使用 WeakMap :ml-citation{ref="1" data="citationList"}
const reactiveMap = new WeakMap();
function createReactiveObject(target) {if (reactiveMap.has(target)) {return reactiveMap.get(target);}const proxy = new Proxy(target, { /* 处理逻辑 */ });reactiveMap.set(target, proxy);return proxy;
}
// 组件销毁后,target 对象被回收,WeakMap 自动清理对应代理
3. 规避循环引用问题
在复杂对象关联场景中,WeakMap 的弱引用特性可避免因相互引用导致的内存无法回收问题。