[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集合**。
- Javascript基础篇
- Array数组
- 数组插入值
- filter()
- forEach()
- push()
- pop()
- unshift()
- shift()
- valueOf()
- 面向对象思想
- Javascript 面向对象编程(一):封装
- Javascript面向对象编程(二):构造函数的继承
- Javascript面向对象编程(三):非构造函数的继承
- 解构
- 数组的解构赋值
- 对象的解构赋值
- 函数参数解构
- 字符串的解构赋值
- 数值和布尔值的解构赋值
- 圆括号问题
- 字符串.
- split()
- charAt()
- charCodeAt()
- concat()
- indexOf()
- lastIndexOf()
- match()
- replace()
- includes()
- 初识递归
- 渲染ul-li树形结构
- 异步函数解决方案
- 1. callback回调函数
- 2. ES6 - Promise
- JavaScript高级程序设计(书)
- 在html中使用JavaScript
- script标签的位置
- 延迟脚本
- 异步脚本
- <noscript>元素
- 基本概念
- 严格模式
- 变量详解
- 数据类型
- typeof操作符
- undefined类型
- Null类型
- Boolean类型
- Number类型
- 深入了解ES6(书)
- var 、let 、 const
- 字符串与正则表达式
- 字符串
- 正则表达式
- 函数
- 函数形参默认值
- 使用不具名参数
- 函数构造器的增强能力
- 扩展运算符
- name属性
- 明确函数的多重用途
- 块级函数
- 箭头函数
- 尾调用优化
- 扩展的对象功能
- 对象类别
- 对象字面量语法的扩展
- ES6对象新增方法
- 重复的对象属性
- 自有属性的枚举顺序
- 更强大的原型
- 解构:更方便的数据访问
- 为什么要用解构?
- 对象解构
- 数组解构
- 混合解构
- 参数解构
- Symbol与Symbol属性
- 创建Symbol
- Symbol的使用方法
- Symbol全局私有属性
- Symbol与类型强制转换
- Symbol属性检索
- Symbol的一些构造方法
- Set集合与Map集合
- Set集合
- Weak Set集合(弱引用Set集合)
- Map集合
- JS标准内置对象
- Object 构造函数及属性
- Object 构造方法
- Symbol 内建对象类的函数及属性
- Set 构造函数及属性
- Weak Set 构造函数及属性
- JS杂项
- 类数组对象
- Class类的理解和使用