WeakMap和WeakSet的核心特性是键或值的弱引用不阻止垃圾回收。WeakMap只接受对象作键、不可遍历;WeakSet只存对象、无size属性且不可遍历;二者均不触发GC,也不能用于缓存或序列化。

WeakMap 和 WeakSet 的核心特性不是“弱引用”本身,而是它们对键(WeakMap)或值(WeakSet)的引用不阻止垃圾回收——这意味着你无法通过它们“持有”对象而不影响其生命周期。
WeakMap 只接受对象作为键,且无法遍历
WeakMap 的 key 必须是对象(包括函数、数组、普通对象),传入原始值(如 "str"、42、true)会直接报错:TypeError: Invalid value used as weak map key。它没有 keys()、values()、entries() 或 forEach 方法,也无法用 for...of 遍历。
常见用途是给第三方对象“附加私有元数据”,又不干扰其回收:
const privateData = new WeakMap();
class Button {
constructor(el) {
this.el = el;
privateData.set(el, { clickedCount: 0, lastClickTime: Date.now() });
}
click() {
const data = privateData.get(this.el);
data.clickedCount++;
}
}
如果 el 被 DOM 移除且无其他引用,它连同 privateData 中对应的条目会被 GC 回收。
立即学习“Java免费学习笔记(深入)”;
WeakSet 只存对象,且不能查 size 或遍历
WeakSet 的成员只能是对象,同样拒绝原始值;它没有 size 属性,也没有 has() 以外的查询方法(注意:has() 是可用的);也不能遍历。它的典型场景是标记“已处理对象”,避免重复操作:
无论从何种情形出发,在目前校长负责制的制度安排下,中小学校长作为学校的领导者、管理者和教育者,其管理水平对于学校发展的重要性都是不言而喻的。从这个角度看,建立科学的校长绩效评价体系以及拥有相对应的评估手段和工具,有利于教育行政机关针对校长的管理实践全过程及其结果进行测定与衡量,做出价值判断和评估,从而有利于强化学校教学管理,提升教学质量,并衍生带来校长转变管理观念,提升自身综合管理素质。
- 在深克隆中防止循环引用:
seen用 WeakSet 存已访问过的源对象 - 在事件监听器中记录“已绑定过 cleanup 的对象”,避免多次调用
cleanup
示例:
const processed = new WeakSet();
function process(obj) {
if (processed.has(obj)) return;
// ...实际处理逻辑
processed.add(obj);
}
只要 obj 外部引用消失,processed 不会阻止它被回收。
WeakMap/WeakSet 不触发 GC,也不保证立即清理
它们不控制垃圾回收时机,只“不阻碍”回收。即使对象已无强引用,GC 也可能尚未运行,此时 get() 或 has() 仍可能返回值。不能依赖它们做“资源释放通知”或“生命周期钩子”。
- 不要用
WeakMap.get(key) === undefined判断对象是否已被回收——它可能只是没设过,或刚设完还没 GC - 不能用 WeakMap 实现缓存(比如 LRU),因为无法枚举、无法控制淘汰逻辑
- Node.js 中可通过
global.gc()(需启动时加--expose-gc)辅助测试,但生产环境禁用
与 Map/Set 的关键差异总结
WeakMap/WeakSet 的限制全是为支持弱引用让路:
-
Map键可以是任意类型;WeakMap键只能是对象 -
Set用Object.is()比较值;WeakSet同样只靠引用相等,但无法迭代验证 -
Map.prototype.clear()存在;WeakMap没有clear(),也无法清空——设计上就不可逆 - 序列化(
JSON.stringify)对 WeakMap/WeakSet 无意义,它们不会出现在任何序列化结果中
真正需要弱引用语义时才用它们;想存配置、缓存、索引,还是老实用 Map/Set —— 弱引用不是免费午餐,是带约束的取舍。










