JS WeakMap/WeakSet
学习WeakMap · 难度:进阶 · +15XP
JavaScript WeakMap 与 WeakSet 详解
WeakMap 和 WeakSet 是 ES6 引入的弱引用集合类型。它们的键或值是弱引用,不会阻止垃圾回收,适合存储临时数据或私有属性。
WeakMap 与 Map 的区别
| 特性 | Map | WeakMap |
|---|---|---|
| 键的类型 | 任意类型 | 只能是对象 |
| 引用方式 | 强引用(阻止 GC) | 弱引用(不阻止 GC) |
| 可迭代 | 支持 for...of | 不可迭代 |
| size 属性 | 有 map.size | 无 |
| 方法 | get/set/has/delete/clear | get/set/has/delete |
WeakMap 使用场景
- DOM 节点关联数据:DOM 被移除时自动释放关联数据
- 实现私有属性:数据存储在 WeakMap 中,外部无法访问
- 缓存计算结果:对象被回收时自动清理缓存
// 场景1:DOM 节点关联(不会造成内存泄漏)
const elementData = new WeakMap();
function setData(element, data) {
elementData.set(element, data);
}
function getData(element) {
return elementData.get(element);
}
// DOM 被移除时,关联数据会被自动回收
// 如果用 Map,DOM 移除后仍保留引用,造成泄漏
WeakSet 与私有属性
// WeakSet: 只存储对象,弱引用
const visitedNodes = new WeakSet();
function processNode(node) {
if (visitedNodes.has(node)) {
console.log("该节点已处理过");
return;
}
visitedNodes.add(node);
console.log("节点已处理");
}
// 使用 WeakMap 实现真正私有属性
const _private = new WeakMap();
class User {
constructor(name, password) {
_private.set(this, { password });
this.name = name;
}
checkPassword(input) {
return _private.get(this).password === input;
}
}
const user = new User("admin", "secret123");
console.log(user.name); // "admin"
console.log(user.password); // undefined(私有属性!)
console.log(user.checkPassword("secret123")); // true