在前端开发中,内存泄漏是一个普遍存在的问题。在 JavaScript 中,一些对象可能会因为被应用程序引用而无法被 GC 回收,导致内存泄漏。ES11中引入了弱引用和终结器类,可以有效地解决这些问题。
弱引用(WeakRef)
弱引用是指对对象的引用,不会阻止该对象被垃圾回收。当一个对象被创建时,一个弱引用可以链接到该对象。同时,如果被引用对象被回收,那么弱引用也会被删除。
使用 WeakRef 类,可以创建一个弱引用。
let obj = {key: 'value'}; let ref = new WeakRef(obj);
在上面的示例中,ref 便是一个弱引用。当 obj 被回收时,ref 同时也会被删除。
要获取 obj 对象的值,需要使用 WeakRef 类的deref 方法。
let obj = {key: 'value'}; let ref = new WeakRef(obj); console.log(ref.deref()); // {key: 'value'}
终结器类(FinalizationRegistry)
如果在对象被 GC 垃圾回收时还想执行一些自定义的代码,可以使用 FinalizationRegistry 类,可以在对象被回收前注册一些函数,进行终结工作,例如管理已经使用过的资源。
let registry = new FinalizationRegistry(obj => { // 在对象被 GC 回收时执行一些逻辑 });
FinalizationRegistry 类中需要传入一个函数作为回调函数。当对象被垃圾回收时,回调函数将被执行。
需要注意的是,如果对象被回收前重新引用或分配,回调函数将不会被执行。
let registry = new FinalizationRegistry(() => { console.log('Object is finalize'); }); let obj = {key: 'value'}; registry.register(obj, 'some metadata'); console.log(registry.unregister(obj)); // false
在上面的示例中,FinalizationRegistry 类的 register 方法可用于注册对象以跟踪其垃圾收集。metadata 参数是可选的,它可以包含要存储在跟踪中的有关对象的信息。
综合使用实例
下面是一个综合使用对内存进行管理的示例:
let target = {key: 'value'}; let registry = new FinalizationRegistry(obj => { console.log('Object has been finalize'); }); let ref = new WeakRef(target); console.log(ref.deref()); // {key: 'value'} registry.register(target, {name: 'target'}); console.log(registry.unregister(target)); // false target = null; console.log(ref.deref()); // null
在上述示例中,我们创建了一个对象 target。我们对该对象进行了一个弱引用,同时注册了一个 FinalizationRegistry 实例,以确保对象被垃圾回收时执行某些操作。最后将 target 设置为 null,强制销毁该对象。
总结
在 ES11 中,WeakRef 和 FinalizationRegistry 类的加入,为 JavaScript 开发者提供了一种有效的方式来处理内存管理问题。弱引用和终结器类让开发者可以方便地追踪对象引用的强度,以及在对象被回收时自定义一些处理逻辑。开发者可以根据业务场景使用这些类,有效地避免内存泄漏,提高应用程序的性能和可靠性。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a203ffadd4f0e0ffa171c1