ES6 - WeakSet

算法撷月使
• 阅读 958

在我们进入在WeakSet的使用之前,我们先来看一个用Set来存储对象引用的例子:

let set = new Set();
let key = {};
set.add(key);
key = null;
console.log(set.size); // 1
console.log([...set][0]); // {}

以上代码,我们存储了一个对象的引用key,但是随后我们通过key = null清楚了对象的引用,但是随后我们查看set.size依然得到1,且依然可以通过把set展开到数组取到原本已经被我们清除了引用的key。
之所以会出现这样的结果是因为,Set存储的是对象的强引用,虽然在代码的其他地方已经不存在对此变量的引用,但是javaScript的垃圾回收机制依然不会回收这段地址。这种情况,就会造成我们常说的内存泄漏

而WeakSet就是为了解决上面的问题而存在的,相比Set,WeakSet存的是对象的弱引用。意思就是,如果在代码的其他地方已经不存在任何引用,那么WeakSet也不会再保留这个引用,这样就可以被垃圾回收了。

了解了以上WeakSet的存在背景,现在就来看一下WeakSet的一些特性和使用:
一:初始化WeakSet
一:通过new WeakSet()初始化

let weakSet = new WeakSet();

二:传入可迭代对象初始化

let key1 = {};
let key2= {};
let weakSet = new WeakSet([key1, key2]);

二:WeakSet的add(),delete(),has()方法
区别于Set,WeakSet只有三个方法可用,分别是

1: add() 添加一个元素
2: delete() 删除一个元素
3: has() 查询某个元素是否存在

它们的功能和用法与Set所对应的三个方法一致,只是在参数类型上有所限制,即:
以上三个方法都不能传入基本数据类型,只能传入对象类型。 我们先来看一下代码示例:

let key1 = {name: 'may'};
let key2= {name: 'april'};

let weakSet = new WeakSet([key1, key2]);
console.log(weakSet.has(key1)); // true

weakSet.delete(key2);

let key3 = {name: 'mike'};
let result = weakSet.add(key3);
console.log(result);

最后打印 console.log(result),我们得到结果:

WeakSet {{…}, {…}}
__proto__: WeakSet
[[Entries]]: Array(2)
0:
value: {name: "may"}
1:
value: {name: "mike"}
length: 2

可以看到因为调用delete(key2), 所以我们最后的结果里面没有了key2。

三:WeakSet与Set的区别

WeakSet与Set除了存储的分别是对象的弱引用和强引用之外,还有很多差别,下面我们就来总结一下WeakSet的特性:

1: WeakSet只能不能存储基本数据类型。这几意味着,在初始化和调用add()的时候,都只能传入对象类型的元素。
2: 如果给add()方法传入非对象类型,会抛出错误。给delete()和has()传入非对象类型参数,则总是返回false。
3: WeakSet不可迭代,所以所有迭代的场景都不能使用,例如for-of, 展开运算符等
4: WeakSet不暴露任何的迭代器,例如keys(),values(),这也是其不能被迭代的原因
5: WeakSet不支持forEach()方法
6: WeakSet不支持size属性

以上就是关于WeakSet的基本特性和功能。

点赞
收藏
评论区
推荐文章
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
3年前
Vue 3 深入响应性原理
深入响应性原理终于到了讲解我们Vue的响应式原理,前面我们已经讲解了Map,WeakMap,Set,WeakSet,Proxy,Reflect这几个知识点。那么接下来思考下到底什么是响应式,就比如我们做一个公司的官网,然后要求必须兼容手机端,ipad端,电脑端,内容屏幕大小变化而变化,这些就需要依赖Ja
Easter79 Easter79
3年前
Spring框架学习(四):聊一聊xml配置和Java配置
之前的例子在演示过程中直接使用了xml的配置方式,对于刚刚接触Spring的同学来说肯定也是蒙圈的。这篇我们就从配置开始聊起。在开发过程中,程序员通常使用这两种方式进行Spring的配置:基于XML配置文件配置基于Java代码配置对于第一种配置方式,我们来看一个例子,还是引用之前的。1<?xmlversion
Wesley13 Wesley13
3年前
9、ES6对象的简写。
在写一个对象的时候,ES6给我们提供了一种简写的方式。例子如下:<scripttype"text/javascript"letusername"张三";letage18;//普通方式声明一个对象objletobj{
Stella981 Stella981
3年前
JS 对象数组Array 根据对象object key的值排序sort,很风骚哦
有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak
Wesley13 Wesley13
3年前
Java基础学习总结(8)——super关键字
一、super关键字  在JAVA类中使用super来引用父类的成分,用this来引用当前对象,如果一个类从另外一个类继承,我们new这个子类的实例对象的时候,这个子类对象里面会有一个父类对象。怎么去引用里面的父类对象呢?使用super来引用,this指的是当前对象的引用,super是当前对象里面的父对象的引用。
Wesley13 Wesley13
3年前
10 HashSet HashMap源码 Properties
2HashSet底层是使用HashMap实现的。当使用add方法将对象添加到Set当中时,实际上是将该对象作为底层所维护的Map对象的key,而value则都是同一个Object对象(该对象我们用不上);3\.HashMap底层维护一个Node数组,我们向HashMap中所放置的对象实际上是存储在该数组当中;HashMap中的Pu
3A网络 3A网络
2年前
Redis 存储对象信息是用 Hash 还是 String
Redis存储对象信息是用Hash还是StringRedis内部使用一个RedisObject对象来表示所有的key和value,RedisObject中的type,则是代表一个value对象具体是何种数据类型,它包含字符串(String)、链表(List)、哈希结构(Hash)、集合(Set)、有序集合(Sortedset)。