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

相关推荐
anyup_前端梦工厂2 小时前
了解几个 HTML 标签属性,实现优化页面加载性能
前端·html
前端御书房2 小时前
前端PDF转图片技术调研实战指南:从踩坑到高可用方案的深度解析
前端·javascript
2301_789169542 小时前
angular中使用animation.css实现翻转展示卡片正反两面效果
前端·css·angular.js
风口上的猪20153 小时前
thingboard告警信息格式美化
java·服务器·前端
程序员黄同学3 小时前
请谈谈 Vue 中的响应式原理,如何实现?
前端·javascript·vue.js
爱编程的小庄4 小时前
web网络安全:SQL 注入攻击
前端·sql·web安全
宁波阿成4 小时前
vue3里组件的v-model:value与v-model的区别
前端·javascript·vue.js
柯腾啊5 小时前
VSCode 中使用 Snippets 设置常用代码块
开发语言·前端·javascript·ide·vscode·编辑器·代码片段
weixin_535854225 小时前
oppo,汤臣倍健,康冠科技,高途教育25届春招内推
c语言·前端·嵌入式硬件·硬件工程·求职招聘
扣丁梦想家5 小时前
设计模式教程:装饰器模式(Decorator Pattern)
java·前端·装饰器模式