在 ES6 之后,JavaScript 新增了许多有用的数据结构,例如 Set
和 Map
,以及 WeakSet
和 WeakMap
。本文将深入介绍 WeakSet
的定义、应用场景,以及常见的使用方式。
WeakSet 的定义
与 Set
不同的是,WeakSet
中只能保存对象类型的数据,而不能保存基本类型的数据。WeakSet 中的对象是弱引用,也就是说当对象没有被其他地方引用时,会被自动清除,从而减少内存占用。
WeakSet
与 Set
相比有以下不同:
WeakSet
中的元素是弱引用,当只有WeakSet
内保存的对象没有被其他地方引用时,就会被自动清除,以免造成内存占用与泄漏。WeakSet
没有遍历功能,因为存储的内容有可能随时被删除,而不是稳定的。WeakSet
没有size
属性,也不能被forEach()
遍历。
WeakSet 的应用场景
常见的 Set
用法是保存一些不重复的数据。而 WeakSet
与其有所不同。实际上,Weakset
最主要的用途是在内存占用较大的数据结构中,或是需要对某些值进行自动垃圾回收的场景中。
比如,我们可以将 WeakSet
用于保存 DOM 元素,以免内存占用。
const weakSet = new WeakSet(); weakSet.add(document.querySelector('.demo')); // 向 WeakSet 中添加 DOM 元素
在 Vue.js 内部实现中,$watchEffect 使用了 WeakSet,它创建了一个副作用函数和 dependent 对象之间的映射。当此值变为无效值时,watchEffect 函数将从依赖它的 effect 集合中删除 dependent。
使用示例
假设我们在一个内存占用较大的应用中,需要将表单中一些输入框的值在某些事件上自动清空。为了实现这个功能,我们可以利用 WeakSet
的弱引用特性。
-- -------------------- ---- ------- ----- ------ - --- ---------- -------- ------------- - -------------------- -- - ----------- - --- --- - ---------------------------------------------------------------- -- - ------------------ --- ----------------------------------- - -- - ------------------- -------------- ---
在这个例子中,我们使用 WeakSet 存储输入框的引用,并在表单提交事件上清空表单中的输入框。当页面卸载后,输入框的引用将被 GC 回收从而防止内存泄漏。
总结
WeakSet
可以有效减少内存占用和避免内存泄漏,可以应用在很多常见场景中,例如 Vue.js 的 $watchEffect
方法。不过需要注意的是,WeakSet
与 Set
最大的区别是它不具备遍历功能,仅适用于需要自动垃圾回收或者内存占用较大的场景。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64ad410848841e9894969f0e