ES12 (ECMAScript 2021) 特性总结:WeakRef
1. WeakRef
概述
描述
WeakRef
是 ES12 引入的一个新特性,用于创建对对象的弱引用。弱引用不会阻止垃圾回收器回收对象,即使该对象仍然被弱引用持有。WeakRef
通常与 FinalizationRegistry
结合使用,用于在对象被垃圾回收时执行清理操作。
语法
const weakRef = new WeakRef(targetObject);
主要方法
deref()
:返回弱引用指向的目标对象。如果目标对象已被垃圾回收,则返回undefined
。
2. WeakRef
的用法
创建弱引用
const obj = { name: "Alice" };
const weakRef = new WeakRef(obj);
// 访问目标对象
const target = weakRef.deref();
console.log(target); // { name: "Alice" }
检查对象是否被回收
let obj = { name: "Bob" };
const weakRef = new WeakRef(obj);
// 解除对 obj 的强引用
obj = null;
// 强制触发垃圾回收(仅用于演示,实际环境中不应手动调用)
global.gc();
// 检查对象是否被回收
setTimeout(() => {
const target = weakRef.deref();
console.log(target); // undefined(对象已被回收)
}, 1000);
3. WeakRef
的使用场景
1. 缓存系统
在缓存系统中,可以使用 WeakRef
来缓存对象。当内存不足时,垃圾回收器会自动回收这些对象,从而避免内存泄漏。
示例
const cache = new Map();
function getCachedData(key) {
let cachedRef = cache.get(key);
if (cachedRef) {
const cachedData = cachedRef.deref();
if (cachedData) {
return cachedData;
}
}
// 重新获取数据并缓存
const newData = fetchData(key);
cache.set(key, new WeakRef(newData));
return newData;
}
2. 监听对象生命周期
结合 FinalizationRegistry
,可以在对象被垃圾回收时执行清理操作。
示例
const registry = new FinalizationRegistry((heldValue) => {
console.log(`Object with value ${heldValue} has been garbage collected.`);
});
let obj = { name: "Charlie" };
const weakRef = new WeakRef(obj);
// 注册清理回调
registry.register(obj, "some metadata");
// 解除对 obj 的强引用
obj = null;
// 当 obj 被垃圾回收时,会触发清理回调
3. 避免内存泄漏
在需要持有对象引用但又不想阻止垃圾回收的场景中,WeakRef
是一个理想的选择。
示例
class EventListener {
constructor(target) {
this.targetRef = new WeakRef(target);
this.handleEvent = this.handleEvent.bind(this);
target.addEventListener("click", this.handleEvent);
}
handleEvent(event) {
const target = this.targetRef.deref();
if (target) {
console.log("Event triggered on:", target);
} else {
// 目标对象已被回收,清理事件监听器
event.currentTarget.removeEventListener("click", this.handleEvent);
}
}
}
4. 注意事项
-
垃圾回收的不确定性:
- 垃圾回收的时机由 JavaScript 引擎决定,无法手动控制。
- 即使对象不再被强引用,垃圾回收也可能不会立即执行。
-
避免滥用:
WeakRef
和FinalizationRegistry
是高级特性,通常只在特定场景下使用。- 过度使用可能导致代码难以理解和维护。
-
兼容性:
- 确保目标运行环境支持
WeakRef
和FinalizationRegistry
。
- 确保目标运行环境支持
5. 总结
特性 | 描述 | 使用场景 |
---|---|---|
WeakRef | 创建对对象的弱引用,不会阻止垃圾回收器回收对象 | 缓存系统、监听对象生命周期、避免内存泄漏 |
deref() | 返回弱引用指向的目标对象,若对象已被回收则返回 undefined | 检查对象是否仍然可用 |
结合 FinalizationRegistry | 在对象被垃圾回收时执行清理操作 | 对象生命周期管理、资源清理 |