weakmap 不接受原始类型作键,因其无内存地址无法弱引用,尝试会报错;map 允许原始键且按值相等查找,生命周期等于 map 实例;对象键在 weakmap 中可被 gc 自动清理,在 map 中则被强持有。

原始类型在 WeakMap 中根本不能作为键,所以谈不上“生存周期差异”——这是个前提性限制,不是行为差异。
WeakMap 不接受原始值作键,因为弱引用对它没意义
WeakMap 的“弱引用”只对堆内存中的对象有效。原始值(如字符串、数字、布尔值)存储在栈中或作为立即量存在,没有独立的内存地址,无法被“弱引用”或“强引用”。尝试用原始值设为 WeakMap 键会直接报错:
-
new WeakMap().set('hello', 1)→ TypeError: Invalid value used as weak map key - 而
new Map().set('hello', 1)完全合法,且该字符串键会长期存在
Map 中原始键的生命周期由值相等性决定,与引用无关
Map 允许任意值作键,原始键的存续不依赖引用计数,而是靠“值相等”来查找和保留:
- 字符串
'foo'作为键,后续用另一个字面量'foo'调用get()仍能命中 - 这个键不会因变量赋值变化而消失;只要 Map 实例存在,它就一直可访问
- 它的“生命周期”等于 Map 实例的生命周期,不受 GC 影响
对象键在两者中的行为才体现真正的生命周期差异
只有对象才能同时用于 Map 和 WeakMap,这时差异才显现:
- 在 Map 中:
map.set(obj, 'data')后即使obj = null,obj仍被 Map 强持有,无法被 GC 回收 - 在 WeakMap 中:
wm.set(obj, 'data')后若obj = null且无其他引用,GC 可随时回收该对象,WeakMap 也自动丢弃对应条目 - 这个自动清理机制是 WeakMap 存在的根本价值,原始类型天生不具备这种场景
简单说:原始类型和 WeakMap 是“不兼容”,不是“生命周期不同”。真正需要对比生命周期的,只能是对象键。










