JS WeakMap 详细用法从基础到实战指南
更新时间:2026年05月22日 09:11:16 作者:chenlight
WeakMap是JavaScript中的一个集合类型,类似于普通的Map,但键必须是对象,当键对象不再被引用时,WeakMap会自动将其从集合中删除,有助于垃圾回收机制回收内存,WeakMap中的键是不可以被枚举的,文章总结了WeakMap的核心特法、应用场景和与Map的区别,感兴趣的朋友一起看看吧
WeakMap 是 JavaScript 中的一个集合类型,它类似于普通的 Map,但有几个关键的不同之处:
- 键的限制:
WeakMap的键必须是对象,而不能是原始值(如字符串、数字等)。 - 内存管理:当键对象不再被引用时,
WeakMap会自动将其从集合中删除,这有助于垃圾回收机制回收内存。 - 不可枚举:
WeakMap中的键是不可以被枚举的。
WeakMap 是 ES6 新增的弱引用键值对集合,核心特点:
- 键必须是对象(不能是原始值:字符串 / 数字 / 布尔等)
- 键是弱引用:键对象没有其他引用时,会被垃圾回收自动清理(不造成内存泄漏)
- 不可枚举(没有
keys()/values()/forEach(),也不能用for...of) - 只有核心方法:
set()/get()/has()/delete()
一、基础用法(完整示例)
// 1. 创建 WeakMap
const wm = new WeakMap();
// 2. 定义对象作为键(原始值不能做键)
let user = { name: "张三" };
let info = { age: 20 };
// 3. set(key, value):添加键值对
wm.set(user, "用户信息");
wm.set(info, { id: 1001 });
// 4. get(key):获取值
console.log(wm.get(user)); // 输出:用户信息
// 5. has(key):判断是否存在
console.log(wm.has(info)); // 输出:true
// 6. delete(key):删除键值对
wm.delete(info);
console.log(wm.has(info)); // 输出:false错误用法(键不能是原始值)
// 报错:Invalid value used as weak map key
wm.set("字符串键", 123);
wm.set(123, "数值键");二、核心特性:弱引用(最重要!)
WeakMap 的键是弱引用,如果键对象不再被其他变量引用,垃圾回收机制会自动回收该对象,并从 WeakMap 中移除,不会造成内存泄漏。
对比:Map 会造成内存泄漏,WeakMap 不会
// 1. 使用 Map(强引用)
let obj = { id: 1 };
const map = new Map();
map.set(obj, "数据");
obj = null; // 手动释放引用
// Map 中依然保留 obj,不会被回收 → 内存泄漏
// 2. 使用 WeakMap(弱引用)
let obj2 = { id: 2 };
const weakMap = new WeakMap();
weakMap.set(obj2, "数据");
obj2 = null; // 手动释放引用
// 没有其他引用 → 垃圾回收自动清理 obj2 和 weakMap 中的键值对三、最常用实战场景
场景 1:给 DOM 元素附加数据(无内存泄漏)
操作 DOM 时,用 WeakMap 存储关联数据,DOM 被删除后数据自动回收:
const btn = document.querySelector("#btn");
const domData = new WeakMap();
// 给 DOM 绑定数据
domData.set(btn, { clickCount: 0 });
// 使用数据
btn.addEventListener("click", () => {
const data = domData.get(btn);
data.clickCount++;
console.log(data.clickCount);
});
// DOM 被删除时 → WeakMap 自动清理,无内存泄漏
// btn.remove();场景 2:私有属性(模拟类的私有数据)
利用 WeakMap 实现真正私有(外部无法访问,不会被遍历):
const _private = new WeakMap();
class User {
constructor(name) {
// 私有数据存在 WeakMap 中
_private.set(this, { name });
}
getName() {
return _private.get(this).name;
}
}
const u = new User("李四");
console.log(u.getName()); // 李四
console.log(u.name); // undefined(真正私有)场景 3:缓存对象关联数据
const cache = new WeakMap();
// 缓存计算结果
function getCachedData(obj) {
if (cache.has(obj)) {
return cache.get(obj);
}
// 模拟耗时计算
const result = obj.id * 100;
cache.set(obj, result);
return result;
}四、WeakMap 可用方法汇总
| 方法 | 作用 |
|---|---|
wm.set(keyObj, value) | 添加 / 更新键值对 |
wm.get(keyObj) | 获取对应值 |
wm.has(keyObj) | 判断是否存在,返回布尔值 |
wm.delete(keyObj) | 删除指定键值对 |
wm.clear() | 已废弃,不要使用 |
五、WeakMap vs Map(关键区别)
| 特性 | WeakMap | Map |
|---|---|---|
| 键类型 | 只能是对象 | 任意类型(对象 / 字符串 / 数字等) |
| 引用类型 | 弱引用(自动垃圾回收) | 强引用(不会自动回收) |
| 内存泄漏 | 不会 | 可能会 |
| 枚举 | 不可枚举(无迭代) | 可枚举(keys/values/entries) |
| 大小 | 无 size 属性 | 有 size |
总结
- 什么时候用 WeakMap:
- 给对象附加额外数据
- DOM 元素关联数据
- 类私有属性
- 不想造成内存泄漏的缓存
- 记住核心:键必须是对象 + 弱引用自动回收 + 不可枚举
- 它是专门为避免对象关联数据造成内存泄漏设计的 API
到此这篇关于JS WeakMap 详细用法:从基础到实战的文章就介绍到这了,更多相关js weakmap用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!


最新评论