weakmap 是唯一能安全为对象附加私有元数据而不干扰其生命周期的内置工具,因其键为弱引用,对象仅被 weakmap 引用时可被垃圾回收,对应条目自动消失。

WeakMap 是唯一能安全为对象附加私有元数据而不干扰其生命周期的内置工具。它的键是弱引用,只要对象在其他地方失去所有强引用,就能被垃圾回收器正常清理,对应条目也自动消失。
为什么 WeakMap 能做到“不干扰垃圾回收”
普通 Map 或对象属性会对键(如 DOM 元素、类实例)产生强引用,阻止 GC 回收;WeakMap 的键则是弱引用——它不计入引用计数。只要对象只被 WeakMap 键着,没有其他变量、闭包或属性指向它,GC 就能释放它,WeakMap 中的条目也随之失效。
- 键必须是对象(不能是字符串、数字等原始值)
- 值可以是任意类型,但值本身仍是强引用(若值里存了其他对象,那些对象不会因 WeakMap 而被自动释放)
- 没有 size、keys()、clear() 等方法,无法遍历或批量操作——这反而是保障自动清理的关键设计
典型使用方式:给类实例加私有字段
ES6 类没有原生私有字段时,WeakMap 是最干净的模拟方案:
const _private = new WeakMap();
<p>class Button {
constructor(label) {
// 私有状态仅通过 WeakMap 绑定到 this
_private.set(this, { label, clickCount: 0 });
}</p><p>click() {
const data = _private.get(this);
data.clickCount++;
}</p><p>getLabel() {
return _private.get(this)?.label;
}
}</p><p>// 实例销毁后,_private 中对应条目自动消失
const btn = new Button("Submit");
btn = null; // 外部引用断开,实例可被 GC,WeakMap 条目同步清理
</p>
绑定 DOM 元素元信息,避免内存泄漏
动态添加/移除节点时,常需附带状态(如加载中标志、上次更新时间)。用 WeakMap 可彻底规避手动清理遗漏:
- 创建全局 WeakMap 实例:const elementMeta = new WeakMap()
- 每次操作前检查是否存在:if (!elementMeta.has(el)) { elementMeta.set(el, { isLoading: false }) }
- 事件监听器可直接读取 meta,无需挂载到元素上(避免污染属性名或引发冲突)
- 元素被 remove() 或页面跳转后,只要没其他 JS 变量持有它,就会被回收,meta 自动消失
缓存计算结果,实现自动失效
对某个对象执行昂贵运算时,结果缓存依赖对象本身生命周期:
const cache = new WeakMap();
<p>function computeHash(obj) {
if (cache.has(obj)) return cache.get(obj);</p><p>const hash = /<em> 耗时逻辑,比如深比较或序列化 </em>/;
cache.set(obj, hash);
return hash;
}</p><p>// 当 obj 被回收,cache 条目自然消失,无需手动 delete 或定时清理
</p>










