在 ES12 中,JavaScript 引入了强大且令人兴奋的 WeakRefs 对象特性。该特性为前端开发者提供了一种垃圾回收动态跟踪的方法,并帮助开发人员在应用程序中避免一些常见的内存泄漏问题。
什么是 WeakRefs 对象?
WeakRefs 对象是一种新的 JavaScript 对象类型,它可以跟踪其他对象,而不会阻止其被垃圾回收器回收。在此类跟踪中,当被跟踪对象被回收时,WeakRefs 对象会成为 null。
和一般的引用不同,WeakRefs 对象并不强制维持一个指向对象的引用,这也就是为什么它被称为“weak”(弱)的原因。
WeakRefs 对象的作用
WeakRefs 对象有助于避免内存泄漏。尤其是在 JavaScript 应用中,由于闭包、Event Listener 来源丢失、循环引用等原因,内存泄漏是很常见的问题。WeakRefs 对象的引入,使得开发者可以跟踪对象的生命周期,从而检测和避免内存泄漏。
下面我们来看看具体的应用场景。
例子一:清除事件监听器
我们经常在开发过程中会遇到下面的情况:往 DOM 元素添加了事件监听器后,忘记移除该监听器,这会造成内存泄漏,导致事件监听器不能被垃圾回收。
使用 WeakRefs 对象,我们可以跟踪事件监听器是否被垃圾回收,通过如下代码,我们可以在事件监听器被回收时,移除该事件监听器。
-- -------------------- ---- ------- ----- ------------------- - ---------- - --- ---------- ---------------------- --------- - --- --------- - ------------------------- -- --- -- ------------------ --------------- - --- ------ ----------------------- ------------------- ------------------------- ----------- - --------------- -------- - --- --------- - ------------------------- -- --- --- --------- - --------------- -- --- ------ --- ---- -------- -- ---------- - --- --- - ----------------- -- ----- ------------- ---- --------------------------------- - - -
我们在使用 addEventListener
方法的时候,会把监听器加入到 Set
中,并且把整个 container
对象作为参数作为 WeakRefs 的 key 存储在 #listeners
的 WeakMap 中。
在 fireEvent
中,我们直接使用 deref()
方法获取监听器,如果能够获取到,说明监听器还没有被回收,然后执行回调函数;否则说明该监听器已经被移除,我们则从 #listeners
中把该监听器删除。
例子二:清除动画帧
例如包含 requsetAnimationFrame
的动画,当忘记清除动画帧时,会导致内存泄漏。我们可以使用 WeakRefs 对象,实现动画帧的自动清除。
-- -------------------- ---- ------- ----- -------------- - --- ---------- -------- ----------------- - --- ---- ---------- -------- -- ------------------------- - ----- ----------- - ---------------- -- ------------- - ----------------------- - ---- - -------------------------------- - - ------------------------------ - -------- -------------------------- - ---------------------------- --- ------------------- -
在程序中,当调用 addFrameCallback
时,我们把需要执行的回调函数存储在 frameCallbacks
中,而不是直接将回调函数存储在数组中。当 render
函数被调用时,我们循环迭代 frameCallbacks
,当回调函数被垃圾回收时,通过 weak reference,我们会从 frameCallbacks
中将回调函数删除。这样,在动画完成后,无论是否手动清除,这段内存空间都会被自动清除,避免了内存泄漏。
总结
ES12 中的 WeakRefs 对象为前端开发者提供了一种垃圾回收动态跟踪的新方法,可以帮助开发者避免内存泄漏的问题。我们可以通过多种情况来灵活运用该特性,如 DOM 元素事件监听器的清除、动画帧的清除等。在开发过程中,学习和掌握这一特性,有助于提高开发效率、优化性能,提升整体开发质量。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64e05de9f6b2d6eab3b71b07