WeakMap 和 WeakSet 是 JavaScript 中支持弱引用的集合类型,WeakMap 键必须为对象且不可遍历、无 size,用于私有元数据缓存;WeakSet 仅存对象、不可遍历、无 size,适用于对象状态标记,二者均避免内存泄漏。
WeakMap 和 WeakSet 是 JavaScript 中两种“弱引用”的集合类型,它们的核心特点是:不阻
止垃圾回收机制回收其键(WeakMap)或值(WeakSet)所引用的对象。换句话说,只要对象在其他地方不再被强引用,即使它还在 WeakMap 的键里、或 WeakSet 里,也会被自动清理掉。
WeakMap 类似于 Map,但有三个关键限制:
这些限制不是缺陷,而是为了配合“弱引用”语义——不让引擎因可枚举、可计数而必须保留内部引用。常见用途包括:给第三方对象“悄悄”附加私有元数据,又不干扰它的生命周期。比如:
const cache = new WeakMap();当 obj 被外部丢弃后,cache 里的这一项会自动消失,不会造成内存泄漏。
WeakSet 类似于 Set,但也有严格限制:
典型使用场景是标记对象状态,比如记录哪些 DOM 元素已被初始化过:
const initialized = new WeakSet();一旦 el 从 DOM 中移除且无其他引用,WeakSet 自动释放它,无需手动清理。
普通 Map/Set 对键或值是强引用。如果你把一个 DOM 元素存进 Map,即使页面已移除该元素、JS 代码也再没提它,只要 Map 还持有它,它就无法被 GC 回收——这就成了内存泄漏。WeakMap/WeakSet 则允许这种“临时绑定”,让对象生命周期完全由业务逻辑决定,而不是被集合意外延长。
需要遍历、计数、存原始值?用 Map/Set。需要“临时关联”“状态标记”“避免泄漏”?选 WeakMap/WeakSet。它们不是增强版,而是特殊场景下的安全补充。本质上,它们的存在,是为了让 JS 在保持动态性的同时,也能写出更健壮的内存管理逻辑。
基本上就这些。