JavaScript WeakMap 使用详解
本文详解 JavaScript 中的 WeakMap 对象,介绍其语法、属性及常用方法。重点解析 WeakMap 通过弱引用键对象避免内存泄漏的优势,对比传统 Map 的性能差异,并提供封装带 clear 方法的示例代码,帮助开发者在需要关联对象数据且不影响垃圾回收的场景中正确使用。
WeakMap 对象用于存储键值对集合,其中键持有弱引用。其键必须为对象类型,而值可以是任意类型的数据。
语法
new WeakMap([iterable])
参数
iterable:可选参数,表示一个数组(包含二元数组)或其他可迭代对象,其元素为键值对。每个键值对将被添加到新的 WeakMap 中。若值为 null,则被视为 undefined。
描述
WeakMap 的键只能是 Object 类型。原始数据类型(如 Symbol)不能作为键使用。
Why WeakMap?
在 JavaScript 中,Map API 通常通过两个数组(分别存储键和值)来实现。设置值时,键和值会被同时添加到数组末尾,使索引对应。取值时需遍历所有键,再通过索引从值数组中检索。
这种实现存在两个主要缺点:首先,赋值和搜索操作的时间复杂度均为 O(n),因为需要遍历整个数组进行匹配;其次,数组对每个键和值的引用可能导致内存泄漏,即使没有其他引用存在,垃圾回收算法也无法回收这些对象。
相比之下,原生 WeakMap 持有键对象的“弱引用”,这意味着当没有其他引用存在时,垃圾回收机制能正确运行。原生 WeakMap 的结构特殊且高效,其映射的键仅在未被回收时才有效。
由于这种弱引用机制,WeakMap 的键是不可枚举的(没有方法能列出所有键)。如果键可枚举,其列表将受垃圾回收影响,导致结果不确定。因此,若需获取对象键的列表,应使用 Map。
基本而言,若需向对象添加数据且不希望干扰垃圾回收机制,即可使用 WeakMap。
属性
- WeakMap.length
length 属性的值为 0。
- WeakMap.prototype
WeakMap 构造器的原型,允许向所有 WeakMap 对象添加属性。
WeakMap 实例
所有 WeakMap 实例均继承自 WeakMap.prototype。
属性
WeakMap.prototype.constructor:返回创建 WeakMap 实例的原型函数,默认即为 WeakMap 函数。
方法
- WeakMap.prototype.delete(key)
移除与 key 关联的对象。执行后,WeakMap.prototype.has(key) 将返回 false。
- WeakMap.prototype.get(key)
返回与 key 关联的对象;若没有 key 关联对象,则返回 undefined。
- WeakMap.prototype.has(key)
根据是否存在 key 关联对象,返回一个 Boolean 值。
- WeakMap.prototype.set(key, value)
在 WeakMap 中设置一组 key 关联对象,并返回该 WeakMap 对象。
示例
使用 WeakMap
const wm1 = new WeakMap(),
wm2 = new WeakMap(),
wm3 = new WeakMap();
const o1 = {},
o2 = function(){},
o3 = window;
wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // value可以是任意值,包括一个对象或一个函数
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // 键和值可以是任意对象,甚至另外一个WeakMap对象
wm1.get(o2); // "azerty"
wm2.get(o2); // undefined,wm2中没有o2这个键
wm2.get(o3); // undefined,值就是undefined
wm1.has(o2); // true
wm2.has(o2); // false
wm2.has(o3); // true (即使值是undefined)
wm3.set(o1, 37);
wm3.get(o1); // 37
wm1.has(o1); // true
wm1.delete(o1);
wm1.has(o1); // false
实现一个带有 .clear() 方法的类 WeakMap 类
class ClearableWeakMap {
constructor(init) {
this._wm = new WeakMap(init)
}
clear() {
this._wm = new WeakMap()
}
delete(k) {
return this._wm.delete(k)
}
get(k) {
return this._wm.get(k)
}
has(k) {
return this._wm.has(k)
}
set(k, v) {
this._wm.set(k, v)
return this
}
}
规范
| Specification | Status | Comment |
|---|---|---|
| ECMAScript 2015 (6th Edition, ECMA-262) WeakMap |
Standard | Initial definition. |
| ECMAScript (ECMA-262) WeakMap |
Living Standard |
以上就是 JavaScript WeakMap 使用详解的详细内容,更多关于 JavaScript WeakMap 的资料请关注本站其它相关文章!
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
