ES12 新特性 FinalizationRegistry 的使用

436 阅读1分钟

FinalizationRegistry

FinalizationRegistry 是 ECMAScript 2021(ES12)引入的新特性。它在 JavaScript 标准的 ECMA-262 第 12 版 中被添加。MDN 对他的描述是

FinalizationRegistry provides a way to request that a cleanup callback get called at some point when a value registered with the registry has been reclaimed (garbage-collected). (Cleanup callbacks are sometimes called finalizers.)

一句话来概括就是提供了一种在对象被垃圾回收时执行清理操作(回调函数)的机制,有两个 API,来看一段使用的示例

const finalRegistry = new FinalizationRegistry((value) => {
  console.log(
    "对象被垃圾回收时触发,value 为 register 方法的第二个参数,不传的话为 undefined",
    value
  );
});

let a = { name: "a" };
let b = { age: 18 };
let c = { hobby: "game" };

finalRegistry.register(a); //注册对象
finalRegistry.register(b, "this is b"); // 第二个参数会被当成回调函数的参数
finalRegistry.register(c, "this is c", c); // 第三个参数用于取消监听

a = null;
// 打印 undefined
b = null;
// 打印 this is b

// 取消注册回调函数
finalRegistry.unregister(c);

// 不会打印
c = null;

register

接受三个参数

  • target:必传,监听的对象
  • heldValue:必传,触发回调函数的时候会将此值传递过去(但是其实也可以不传,默认就是 undefined,不知道为什么 MDN 上标记为必传 🤷)
  • unregisterToken:如果想使用 unregister 方法去取消监听回收事件的话,就传递第三个参数,FinalizationRegistry 会保持对他的弱引用,通常使用目标值本身作为注销令牌

unregister

接受一个参数,取消监听

  • unregisterToken: 就是 register 的第三个参数即可

兼容性

大概 20 下半年才开始实现,还是比较新的,我去 google 了一下也没有发现有 ployfill 的三方库实现

image.png