垃圾回收判断对象是否该被清理的核心依据是可达性:从全局根出发能通过强引用链访问到的对象被视为“活着”,弱引用(如WeakMap的键、WeakSet的成员)不参与可达性判定,GC标记阶段会忽略它们,确保仅被弱引用的对象可被正常回收。

垃圾回收(GC)判断一个对象是否该被清理,核心依据是“可达性”:只要从全局根(比如 window、当前执行上下文的局部变量等)出发,能通过强引用链访问到某个对象,它就被视为“活着”,不能回收。
弱引用不参与可达性判定
WeakMap 的键、WeakSet 的成员,都是弱引用。这意味着:GC 在标记阶段会完全忽略它们。哪怕一个 DOM 节点只作为 WeakMap 的 key 存在,而页面上已把它 remove() 掉,也没有其他变量指向它——那它就是不可达的,会被正常回收。WeakMap 中对应的键值对也会随之消失,无需手动清理。
对比强引用导致的泄漏风险
用普通 Map 缓存 DOM 数据时,问题就来了:
- Map 对 key 是强引用,节点即使从 DOM 树移除,仍因被 Map 持有而“存活”
- 关联的数据(比如事件回调、状态对象)也跟着滞留内存
- 动态增删大量元素的场景下,这种泄漏会快速累积,引发卡顿甚至崩溃
典型防泄漏用法
WeakMap 存私有元数据:给节点附加状态而不挂载属性
例:缓存表单校验结果、记录懒加载状态、保存组件实例上下文
WeakSet 标记已处理节点:避免重复初始化或绑定事件
例:在事件代理中跳过已监听的元素;在 IntersectionObserver 回调里跳过已进入视口的项
关键限制即安全保证
WeakMap/WeakSet 不可遍历、没有 size、不能 clear()——这些“缺陷”恰恰是设计使然:
立即学习“Java免费学习笔记(深入)”;
- 无法枚举,意味着外部代码无法意外依赖其内容做逻辑判断
- 无 size 属性,避免开发者误以为能靠它做生命周期监控
- 不支持原始值作 key/value,强制聚焦于对象生命周期管理场景


















