WeakMap 通过弱引用 DOM 节点防止内存泄漏,节点移除且无其他强引用时自动被 GC 回收,对应条目随即消失;键必须是对象(如 Node 实例),不支持遍历和 size 查询,适合绑定私有状态而不污染节点或阻塞回收。

WeakMap 是 JavaScript 中专为“键值对绑定且不阻止垃圾回收”设计的数据结构,特别适合给 DOM 节点附加私有状态或扩展数据——既避免污染节点属性,又不会造成内存泄漏。
为什么用 WeakMap 而不是普通 Map 或对象?
DOM 节点是可被 JavaScript 引用的对象。如果用普通对象(如 {node: data})或 Map 存储,节点引用会一直存在,即使该节点从 DOM 中移除、也没其他 JS 引用,它仍无法被 GC 回收,导致内存泄漏。WeakMap 的键是“弱引用”,只要节点在 DOM 中被移除且无其他强引用,它就会自动从 WeakMap 中消失,无需手动清理。
基本用法:创建 WeakMap 并绑定数据
只需一个 WeakMap 实例,用 DOM 节点作键,任意值(对象、函数、原始值包装等)作值:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
const nodeData = new WeakMap();
// 绑定数据
const button = document.querySelector('#my-btn');
nodeData.set(button, {
clickCount: 0,
lastClicked: null,
handler: () => console.log('clicked')
});
// 读取数据
const data = nodeData.get(button);
if (data) {
data.clickCount++;
data.lastClicked = Date.now();
}
// 检查是否已绑定
if (nodeData.has(button)) {
// 可安全操作
}
实用场景示例
常见需求可直接用 WeakMap 解决:
立即学习“Java免费学习笔记(深入)”;
- 事件处理器的上下文绑定:把 handler 和绑定参数存起来,避免重复添加或闭包泄漏
- 组件级私有状态:比如自定义元素中保存渲染状态、动画帧 ID、定时器句柄
- 防抖/节流控制:每个节点独立维护自己的 timer ID,移除节点时自动失效
-
样式/行为开关标记:如
nodeData.set(el, { disabled: true }),比 class 或 dataset 更语义化且不可被开发者误改
注意事项与限制
WeakMap 有几点必须注意:
- 键只能是对象(包括 DOM 节点),不能是字符串、数字或 null
- 不支持遍历(没有 keys()、values()、entries()),也不能获取 size,这是有意为之的设计——确保“弱引用”语义不被破坏
- 不能用 document.createElement('div') 这类未插入 DOM 的节点做键?可以,只要它是对象实例;但若之后完全丢弃引用,它也会被自动清理
- 多个模块共用同一个 WeakMap 实例更安全;全局 WeakMap 不必担心命名冲突,也不建议用多个 WeakMap 分散管理同一类节点

















