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 在对象被垃圾回收时执行清理操作 对象生命周期管理、资源清理

相关推荐
黑色的糖果12 分钟前
vue中tailwindcss插件的引入及使用
前端·javascript·vue.js
戌中横17 分钟前
JavaScript——预解析
前端·javascript·学习
木斯佳1 小时前
前端八股文面经大全:26届秋招滴滴校招前端一面面经-事件循环题解析
前端·状态模式
光影少年2 小时前
react状态管理都有哪些及优缺点和应用场景
前端·react.js·前端框架
saber_andlibert3 小时前
TCMalloc底层实现
java·前端·网络
逍遥德3 小时前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
冻感糕人~3 小时前
【珍藏必备】ReAct框架实战指南:从零开始构建AI智能体,让大模型学会思考与行动
java·前端·人工智能·react.js·大模型·就业·大模型学习
程序员agions3 小时前
2026年,“配置工程师“终于死绝了
前端·程序人生
alice--小文子3 小时前
cursor-mcp工具使用
java·服务器·前端
晚霞的不甘3 小时前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d