ES12 weakRefs的用法和使用场景

ES12 (ECMAScript 2021) 特性总结:WeakRef

1. WeakRef 概述

描述

WeakRef 是 ES12 引入的一个新特性,用于创建对对象的弱引用。弱引用不会阻止垃圾回收器回收对象,即使该对象仍然被弱引用持有。WeakRef 通常与 FinalizationRegistry 结合使用,用于在对象被垃圾回收时执行清理操作。

语法

javascript 复制代码
const weakRef = new WeakRef(targetObject);

主要方法

  • deref():返回弱引用指向的目标对象。如果目标对象已被垃圾回收,则返回 undefined

2. WeakRef 的用法

创建弱引用

javascript 复制代码
const obj = { name: "Alice" };
const weakRef = new WeakRef(obj);

// 访问目标对象
const target = weakRef.deref();
console.log(target); // { name: "Alice" }

检查对象是否被回收

javascript 复制代码
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 来缓存对象。当内存不足时,垃圾回收器会自动回收这些对象,从而避免内存泄漏。

示例
javascript 复制代码
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,可以在对象被垃圾回收时执行清理操作。

示例
javascript 复制代码
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 是一个理想的选择。

示例
javascript 复制代码
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. 注意事项

  1. 垃圾回收的不确定性

    • 垃圾回收的时机由 JavaScript 引擎决定,无法手动控制。
    • 即使对象不再被强引用,垃圾回收也可能不会立即执行。
  2. 避免滥用

    • WeakRefFinalizationRegistry 是高级特性,通常只在特定场景下使用。
    • 过度使用可能导致代码难以理解和维护。
  3. 兼容性

    • 确保目标运行环境支持 WeakRefFinalizationRegistry

5. 总结

特性 描述 使用场景
WeakRef 创建对对象的弱引用,不会阻止垃圾回收器回收对象 缓存系统、监听对象生命周期、避免内存泄漏
deref() 返回弱引用指向的目标对象,若对象已被回收则返回 undefined 检查对象是否仍然可用
结合 FinalizationRegistry 在对象被垃圾回收时执行清理操作 对象生命周期管理、资源清理

相关推荐
訾博ZiBo10 分钟前
React 状态管理中的循环更新陷阱与解决方案
前端
StarPrayers.24 分钟前
旅行商问题(TSP)(2)(heuristics.py)(TSP 的两种贪心启发式算法实现)
前端·人工智能·python·算法·pycharm·启发式算法
一壶浊酒..42 分钟前
ajax局部更新
前端·ajax·okhttp
DoraBigHead1 小时前
React 架构重生记:从递归地狱到时间切片
前端·javascript·react.js
彩旗工作室2 小时前
WordPress 本地开发环境完全指南:从零开始理解 Local by Flywhee
前端·wordpress·网站
iuuia2 小时前
02--CSS基础
前端·css
kyle~2 小时前
Qt---setAttribute设置控件或窗口的内部属性
服务器·前端·c++·qt
FIN66683 小时前
昂瑞微:射频与模拟芯片领域的国产领军者
前端·人工智能·科技·前端框架·智能
苦夏木禾3 小时前
css实现表格中最后一列固定
前端·javascript·css