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. 避免滥用:

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

    • 确保目标运行环境支持 WeakRef 和 FinalizationRegistry。

5. 总结

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

相关推荐
迅猛龙办公室5 小时前
Python输出当前计算机的系统日期和时间
开发语言·前端·python
小狼154545 小时前
浏览器扩展脚本为什么有时候不生效:注入时机、iframe 和单页路由,多多开票助手
前端·chrome
じòぴé南冸じょうげん5 小时前
油猴脚本突然发现变成灰色了,无法使用?页面不生效?刷新页面没反应?
前端
Csvn7 小时前
组合式 API(Composition API)
前端
火柴就是我8 小时前
Android 打包报错 25.0.3
android·前端
BD_Marathon8 小时前
消息对象中字段的说明
java·前端·python
八荒启·交互动画8 小时前
Web特效025—用 Canvas 2D 做Web特效的定义与边界:这支画笔能做到哪一步
前端·webgl·网页特效·八荒启-交互动画·八荒启
Ai-_Man8 小时前
您您这可以把Dola的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。用AI导出鸭,答案是可以的
开发语言·前端·人工智能·小程序
excel9 小时前
Nuxt 中使用 useHead 优化 SEO 与 GEO
前端
IT_陈寒10 小时前
SpringBoot启动慢得像蜗牛?原来是这个配置在捣鬼
前端·人工智能·后端