WeakMap 是键为弱引用对象的原生集合,不阻止垃圾回收,无遍历方法、无 size 属性,不可用原始值作键,常用于实现私有数据。

WeakMap 是 JavaScript 中一种特殊的键值对集合,它的核心在于键是弱引用的,且键必须是对象。它不阻止垃圾回收器回收作为键的对象——只要该对象在其他地方没有任何强引用,就会被自动清理,对应键值对也随之消失。
为什么 WeakMap 的键是“弱”的?
所谓“弱引用”,是指这个引用不会计入 JavaScript 引擎的可达性分析。垃圾回收器判断一个对象是否可回收,看的是它是否还能被强引用链访问到。WeakMap 对键的持有不构成强引用,因此不影响对象生命周期。
- 如果一个对象只被 WeakMap 当作键引用,而别处再无任何变量、属性或闭包指向它,那它就会被 GC 回收
- 回收发生后,WeakMap 中该键对应的条目自动消失(无需手动清理)
- 值(value)仍是强引用——只要键还存在,值就不会被 GC 回收
WeakMap 不能做什么?这些限制源于弱引用设计
因为键可能随时被回收,引擎无法保证 WeakMap 内容稳定,所以它刻意屏蔽了遍历和统计能力:
- 没有
keys()、values()、entries()方法 - 不支持
for...of或forEach - 没有
size属性,也无法获取当前条目数量 - 不能用字符串、数字、null、undefined 等原始值作键
WeakMap 的典型使用方式
它不是用来替代 Map 的通用容器,而是解决特定问题的工具。常见写法如下:
const privateData = new WeakMap();
class Person {
constructor(name) {
this.name = name;
privateData.set(this, { secret: 'top-level-access' });
}
getSecret() {
return privateData.get(this)?.secret;
}
}
const p = new Person('Alice');
console.log(p.getSecret()); // 'top-level-access'
p = null; // 实例失去强引用
// 下次 GC 运行后,privateData 中对应条目自动消失
这段代码实现了真正意义上的实例私有数据:外部无法通过 privateData 访问任何内容,且不会阻碍 Person 实例回收。
WeakMap 不是手动实现的,而是语言原生机制
你无法用普通 JS 对象或闭包“模拟”出真正的弱引用行为。WeakMap 是由 JavaScript 引擎(V8、SpiderMonkey 等)底层直接支持的原生构造器,其弱引用逻辑与垃圾回收器深度协同。所谓“实现”,其实是引擎在内部维护一张隐式映射表,该表不参与可达性计数,仅在 GC 扫描时同步清理失效项。
开发者只需调用 set()、get()、has()、delete() 即可,其余全部交由运行时自动处理。











