ECMAScript 2021 新增的 WeakRef 和 FinalizationRegistry:如何使用

阅读时长 4 分钟读完

随着时间的推移,前端技术也在不断发展。在 ECMAScript 2021 中,新增了 WeakRef 和 FinalizationRegistry 这两个 API,它们能够帮助我们更好地管理内存,防止内存泄漏问题,本文将详细介绍这两个 API 的使用,并给出实际示例代码。

WeakRef

在介绍 WeakRef 之前,我们先来了解一下 JavaScript 中的内存管理机制。当我们创建一个对象时,它将被分配在内存中。当我们不需要它时,JavaScript 垃圾回收机制会检测它是否已经变成垃圾(即无法再被引用),然后将其从内存中释放,以便其他对象可以重用该内存。

在某些情况下,我们希望在对象不再被使用时自动将其从内存中释放,而不是等待垃圾回收器。WeakRef 提供了这种功能。WeakRef 实例是对另一个对象的弱引用,这意味着它不会防止该对象被垃圾回收器回收,因为垃圾回收器不会将弱引用的对象视为被引用的对象之一。

WeakRef 例子:

上面的代码创建了一个 MyClass 的实例,然后创建了一个 WeakRef 对象 ref。我们可以通过 deref 方法获取弱引用对象,如果弱引用对象是可用的,那么 deref 返回弱引用对象的实例,否则返回 undefined

WeakRef 对象对于临时对象(例如缓存中的对象)非常有用,这些对象可以在当前执行环境不再需要它们时被释放。

FinalizationRegistry

FinalizationRegistry 对象允许我们在对象被垃圾回收时执行回调函数。类似于 WeakRef,FinalizationRegistry 对象不会阻止垃圾回收器回收对象,但会在对象遭受垃圾回收时执行回调函数。

FinalizationRegistry 例子:

-- -------------------- ---- -------
----- ------- -
  ------------- -
    -------------- - ----------------------- -- -- -
      ------------------- -- ----- -----------
    ---
  -
-

----- -------- - --- ------------------------------ -- -
  --------------------- ------------
---
----- --- - --- ----------

上面的代码注册了一个 FinalizationRegistry 对象,在 MyClass 的构造函数中注册了一个回调函数,在对象被垃圾回收时执行这个回调函数。我们可以通过 heldValue 参数获取对象的实例。

如何使用

我们通过一个例子来演示如何使用 WeakRef 与 FinalizationRegistry 来避免内存泄漏。

我们有一个对象数组 objs,每次我们想要将一个对象添加到数组中时,我们可以使用生成的 UUID 作为它的键,并将 WeakRef 对象作为值。创建一个 FinalizationRegistry 对象来跟踪对象的回收。如果对象被垃圾回收了,FinalizationRegistry 将会执行一个回调函数,清理数组 objs 中的对应项。

-- -------------------- ---- -------
----- ---- - ---
----- -------- - --- ------------------------- -- -
  ----- ----- - ------------------ -- -------- --- ------
  -- ------ --- --- -
    ------------------ ---
  -
---

-------- -------------- -
  ----- ---- - ---------------
  ---------------- ---- --- ---------------
  ---------------------- ------
-

-------- -------------- - -- -- ---- -- -

-- --------
---------------- ------------
---------------- ------------
---------------- ------------

-- ----
------- - -----

上面的代码将对象 obj 保存在一个数组中,并通过 WeakRef 的方式保存引用对象。而且通过 FinalizationRegistry 对象来跟踪它们的回收。当我们的数组 objs 中的某个对象变成垃圾时,对应的回调函数会将其从数组中删除。这样,我们就可以避免内存泄漏的问题。

结论

使用新的 WeakRef 和 FinalizationRegistry API,我们可以更好地管理内存,防止内存泄漏问题。在编写 JavaScript 代码时,我们应该始终注意内存使用,并尽可能地避免不必要的对象引用。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/673319670bc820c582408547

纠错
反馈