map 使用强引用阻止键对象被垃圾回收,weakmap 使用弱引用允许键对象被自动回收;前者支持遍历和序列化,后者适用于临时对象附属数据管理。

Map 会阻止其键对象被垃圾回收,WeakMap 不会——这是两者在内存管理上最本质的差异,根源在于引用强度不同。
Map 是强引用,对象不释放
当你用一个对象作为 Map 的键,这个对象就进入了“强引用链”:全局变量 → Map → 键对象。只要 Map 实例还存在,且该对象仍是它的键,垃圾回收器就认为它“可达”,不会回收。
- 即使你把原始变量设为 null,比如
obj = null,Map 内部仍持有着对它的强引用 - 调用
map.keys()仍能遍历出该对象,map.get(obj)在 obj 已为 null 后会返回undefined,但键本身还在 - 大量 DOM 节点或大型配置对象长期作为 Map 键,容易造成内存堆积
WeakMap 是弱引用,对象可随时被回收
WeakMap 对键的引用是“弱”的:它不计入 JavaScript 引擎的可达性判定。一旦键对象在其他地方的引用全部消失,哪怕 WeakMap 还存着它,它也会在下一次 GC 时被清理掉。
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
- 键只能是对象(不能是字符串、数字、Symbol),因为弱引用只对堆中对象有意义
- 没有
.keys()、.values()、.entries()等遍历方法,也无法获知当前有多少项——这是设计使然,避免干扰 GC 判定 - 常见用途:给 DOM 元素挂私有数据、缓存计算结果、避免循环引用泄漏
GC 行为验证的关键细节
实际测试需注意环境与时机:
- Node.js 中需启用
--expose-gc并手动调用global.gc()才能观察到即时回收效果 - 浏览器中无法强制 GC,只能通过反复创建/丢弃大量对象 + 内存快照对比来验证趋势
- WeakMap 的键被回收后,对应条目自动失效:
weakMap.has(key)返回false,weakMap.get(key)返回undefined - WeakMap 本身不阻止自身被回收;若它变成不可达,整个结构连同所有弱键值对都会被一并清理
选型建议:什么时候用哪个?
不看语法糖,只看生命周期和所有权:
- 需要长期持有、显式管理、支持遍历或序列化的键值关系 → 用 Map
- 键是临时对象(如 DOM 节点、事件监听上下文)、数据纯属附属、希望随主对象消亡而自动清理 → 用 WeakMap
- 不确定是否需要长期保留?先用 WeakMap;发现需要遍历或持久化,再改用 Map + 显式清理逻辑










