ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] >[success] # Weak Set集合(弱引用Set集合) 将**对象**存储在**Set实例**中与存储在**变量**中完全一样,只要**Set实例**中的引用存在,**垃圾回收机制就不能释放该对象的内存空间**,于是之前提到的**Set类型**可以被看作是一个**强引用的Set集合**。举个例子: ~~~ let set = new Set(), key = {a:1}; set.add(key); console.log(set.size); // 1 key = null // 移除原始引用 console.log(set.size); // 1 // 重新取回原始引用 key = [...set] // [{a:1}] console.log(key[0]) // {a:1} ~~~ 在这个示例中,将变量**key**,设置为**null**时便清除了对初始化对象的引用,但是**Set集合**却保留了这个引用,你仍然可以使用**展开运算符**将**Set集合**转换成**数组格式**并从这个**数组**的**首个元素**取出该引用。 大部分情况下这段代码运行良好,但有时候你会希望**当其他所有引用都不再存在时,让Set集合中的这些引用随之消失**,举个例子,**如果你在Web页面中通过JavaScript、代码记录了一些DOM元素,这些元素有可能被另一段脚本移除,而你不又不希望自己的代码保留这些DOM元素的最后一个引用。(这个情景被称作内存泄露)** 为了解决这个问题ES6中引入了另一个类型:**Weak Set集合(弱引用Set集合)**。**Weak Set集合**只储存**对象**的**弱引用**,并且**不可以储存原始值**;**集合中的弱引用如果是对象唯一的引用,则会被回收并释放相应内存**。 >[success] ## 创建Weak Set集合 用**WeakSet**构造函数可以创建**Weak Set** 集合,集合支持**3**个方法:**add()**、**has()**、**delete()**。下面这个示例创建了一个**集合**分别调用这**3**个方法: ~~~ let set = new WeakSet(), key = {}; // 向集合Set中添加对象 set.add(key); console.log(set.has(key)); // true set.delete(key); console.log(set.has(key)); // false ~~~ **Weak Set集合**的使用方式与**Set集合**类似,可以向**集合**中添加引用,从中**移除引用**,也可以**检查**集合中是否存在指定对象的引用。 也可以调用**WeakSet**构造函数并传入一个可迭代对象来创建**WeakSet集合**。 ~~~ let key1 = {}, key2 = {}, set = new WeakSet([key1, key2]); console.log(set.has(key1)) // true console.log(set.has(key2)) // true ~~~ 在这个示例中,向**WeakSet构造函数**传入一个含有**两个对象的数组**,最终创建一个包含这两个对象的**Weak Set集合**。请记住,**WeakSet构造函数**不接受任何**原始值**,如果数组中包含其他**非对象值**,程序会抛出错误。 >[success] # 两种Set集合的不同 两者区别: | 方法或属性 | Set集合 | weak Set集合 | | --- | --- | --- | | **集合值**的要求 | **基本类型**和**引用类型** | 只能传入对象 | | **是否可迭代**(循环)**for in** 或者**for of** | **是** | **否** | |**forEach()**|**是**| **否**| |**size属性**|**是**| **否**| **Weak Set集合**的功能看似**受限**,其实这是为了让它能够正确地处理内存中的数据。总之如果你需要**跟踪对象引用**,你更应该使用**Weak Set集合**而不是普通的**Set集合**。