WeakMap 的键必须是对象且为弱引用,不阻止垃圾回收,适合存储临时关联数据以避免内存泄漏;值可为任意类型,但仅键受弱引用保护。

WeakMap 是 JavaScript 中专门用于存储“键值对”的集合类型,它的核心特点是:**键必须是对象,且对键的引用是弱引用**。这意味着只要该对象在其他地方不再被引用,即使它作为 WeakMap 的键存在,垃圾回收器仍能正常回收它——不会因为 WeakMap 的存在而阻止对象销毁。这使得 WeakMap 成为存储临时、关联性数据(如元信息、缓存、私有属性)的理想工具,尤其适合避免内存泄漏。
为什么 WeakMap 能避免干扰垃圾回收
普通 Map 或对象属性会持有对键(或属性名对应对象)的强引用,导致对象无法被 GC 回收;而 WeakMap 的键是弱引用,不计入引用计数。只要没有其他变量或结构引用该对象,它就会被回收,WeakMap 内部对应的条目也会自动消失(不可枚举、无法遍历)。
注意:WeakMap 的 值可以是任意类型(包括原始值、函数、对象),但只有键受弱引用机制保护;值本身不影响键对象的存活。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
典型用法:为对象添加私有/临时状态
比如你想给某个 DOM 元素附加一个仅内部使用的计数器,又不想污染元素自身属性(避免命名冲突或影响序列化):
立即学习“Java免费学习笔记(深入)”;
const elementState = new WeakMap();
<p>function attachCounter(el) {
// 如果 el 还没记录过,初始化为 0
if (!elementState.has(el)) {
elementState.set(el, { count: 0 });
}
const state = elementState.get(el);
state.count++;
return state.count;
}</p><p>// 使用示例
const btn = document.getElementById('myBtn');
console.log(attachCounter(btn)); // 1
console.log(attachCounter(btn)); // 2</p><p>// 页面卸载或 btn 被移除后,只要没其他引用,btn 对象可被 GC,elementState 中对应项自动失效
常见适用场景与注意事项
- 缓存计算结果:以对象为输入参数做昂贵计算,用 WeakMap 缓存结果,对象销毁后缓存自动清理
- 模拟私有字段:配合闭包,在类外部无法访问 WeakMap,实现真正的封装(ES2022 # 私有字段出现前常用方案)
- 避免循环引用泄漏:例如事件监听器中需要引用宿主对象,用 WeakMap 存储回调上下文,防止因闭包强引导致无法释放
- 不能遍历、不能清空、不能获取 size:WeakMap 没有 keys()、values()、entries()、clear() 或 size 属性,这是设计使然,确保其“弱”特性不被滥用
- 键只能是对象(含 null 以外的引用类型):字符串、数字、symbol 等原始值不能作键,会直接报错
对比 Map 和普通对象属性
用普通对象属性(el.__counter = 1)或 Map 存储时,若忘记清理,DOM 元素即使从页面移除、无其他引用,也可能因这些残留属性/条目持续占用内存;WeakMap 则完全无需手动清理,GC 会自动处理,真正“零维护”。

















