WeakSet

含义

WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。

首先,WeakSet 的成员只能是对象,而不能是其他类型的值。

  1. const ws = new WeakSet();
  2. ws.add(1)
  3. // TypeError: Invalid value used in weak set
  4. ws.add(Symbol())
  5. // TypeError: invalid value used in weak set

上面代码试图向 WeakSet 添加一个数值和Symbol值,结果报错,因为 WeakSet 只能放置对象。

其次,WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。

这是因为垃圾回收机制依赖引用计数,如果一个值的引用次数不为0,垃圾回收机制就不会释放这块内存。结束使用该值之后,有时会忘记取消引用,导致内存无法释放,进而可能会引发内存泄漏。WeakSet 里面的引用,都不计入垃圾回收机制,所以就不存在这个问题。因此,WeakSet 适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet 里面的引用就会自动消失。

由于上面这个特点,WeakSet 的成员是不适合引用的,因为它会随时消失。另外,由于 WeakSet 内部有多少个成员,取决于垃圾回收机制有没有运行,运行前后很可能成员个数是不一样的,而垃圾回收机制何时运行是不可预测的,因此 ES6 规定 WeakSet 不可遍历。

这些特点同样适用于本章后面要介绍的 WeakMap 结构。

语法

WeakSet 是一个构造函数,可以使用new命令,创建 WeakSet 数据结构。

  1. const ws = new WeakSet();

作为构造函数,WeakSet 可以接受一个数组或类似数组的对象作为参数。(实际上,任何具有 Iterable 接口的对象,都可以作为 WeakSet 的参数。)该数组的所有成员,都会自动成为 WeakSet 实例对象的成员。

  1. const a = [[1, 2], [3, 4]];
  2. const ws = new WeakSet(a);
  3. // WeakSet {[1, 2], [3, 4]}

上面代码中,a是一个数组,它有两个成员,也都是数组。将a作为 WeakSet 构造函数的参数,a的成员会自动成为 WeakSet 的成员。

注意,是a数组的成员成为 WeakSet 的成员,而不是a数组本身。这意味着,数组的成员只能是对象。

  1. const b = [3, 4];
  2. const ws = new WeakSet(b);
  3. // Uncaught TypeError: Invalid value used in weak set(…)

上面代码中,数组b的成员不是对象,加入 WeaKSet 就会报错。

WeakSet 结构有以下三个方法。

  • WeakSet.prototype.add(value):向 WeakSet 实例添加一个新成员。
  • WeakSet.prototype.delete(value):清除 WeakSet 实例的指定成员。
  • WeakSet.prototype.has(value):返回一个布尔值,表示某个值是否在 WeakSet 实例之中。

下面是一个例子。

  1. const ws = new WeakSet();
  2. const obj = {};
  3. const foo = {};
  4. ws.add(window);
  5. ws.add(obj);
  6. ws.has(window); // true
  7. ws.has(foo); // false
  8. ws.delete(window);
  9. ws.has(window); // false

WeakSet 没有size属性,没有办法遍历它的成员。

  1. ws.size // undefined
  2. ws.forEach // undefined
  3. ws.forEach(function(item){ console.log('WeakSet has ' + item)})
  4. // TypeError: undefined is not a function

上面代码试图获取sizeforEach属性,结果都不能成功。

WeakSet 不能遍历,是因为成员都是弱引用,随时可能消失,遍历机制无法保证成员的存在,很可能刚刚遍历结束,成员就取不到了。WeakSet 的一个用处,是储存 DOM 节点,而不用担心这些节点从文档移除时,会引发内存泄漏。

下面是 WeakSet 的另一个例子。

  1. const foos = new WeakSet()
  2. class Foo {
  3. constructor() {
  4. foos.add(this)
  5. }
  6. method () {
  7. if (!foos.has(this)) {
  8. throw new TypeError('Foo.prototype.method 只能在Foo的实例上调用!');
  9. }
  10. }
  11. }

上面代码保证了Foo的实例方法,只能在Foo的实例上调用。这里使用 WeakSet 的好处是,foos对实例的引用,不会被计入内存回收机制,所以删除实例的时候,不用考虑foos,也不会出现内存泄漏。

es6 WeakSet相关推荐

  1. ES6 WeakSet数据结构 与Set十分相似

    它与Set十分相似,对象的值也不能是重复的,与Set不同点: 1.WeakSet成员只能够是对象. 2.作为WeakSet成员的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是 ...

  2. es6之数据结构 set,WeakSet,mapWeakMap

    {let list = new Set();list.add(1);list.add(2);list.add(1);console.log(list); //Set(2) {1, 2} let arr ...

  3. ES6(三)——Set、WeakSet、Map、WeakMap

    一.Set的基本使用 在ES6之前,我们存储数据的结构主要有两种:数组.对象. 在ES6中新增了另外两种数据结构:Set.Map,以及它们的另外形式WeakSet.WeakMap. Set是一个新增的 ...

  4. set和map去重调用什么方法_你真的了解ES6的Set,WeakSet,Map和WeakMap吗?

    之前在学习 ES6 的时候,看到 Set 和 Map,不知道其应用场景有哪些,只觉得很多时候会用在数组去重和数据存储,后来慢慢才领悟到 Set 是一种叫做集合的数据结构,Map 是一种叫做字典的数据结 ...

  5. 第十六节:ES6新增的 Set 和 WeakSet 是什么东西?

    题外话:往后的章节,跟前面的章节联系越来越紧密,很多知识的讲解建立在前面章节的学习基础上,如果是新来的同学,建议从第一节学起.如果是忘记了前面的内容,前端君也会在适当的时候,加上跳转链接. 什么是Se ...

  6. ES6——Set和WeakSet

    ES6 提供了新的数据结构 Set. 它有七个常用方法: 检查元素是否存在 has(element) 添加元素 add(element) 移除元素 delete(element) 清空集合 clear ...

  7. es6 Map,Set 和 WeakMap,WeakSet

    这些是新加的集合类型,提供了更加方便的获取属性值的方法,不用像以前一样用hasOwnProperty来检查某个属性是属于原型链上的呢还是当前对象的.同时,在进行属性值添加与获取时有专门的get,set ...

  8. ES6 (十三)Set 和 Map 数据结构、WeakSet 和 WeakMap、WeakRef、FinalizationRegistry

    ES6 (十三)Set 和 Map 数据结构.WeakSet 和 WeakMap.WeakRef.FinalizationRegistry 文章目录 ES6 (十三)Set 和 Map 数据结构.We ...

  9. Set、Map、和WeakSet、WeakMap

    文章目录 集合(Set) Set 实例属性 constructor size Set 实例方法 操作方法 遍历方法 WeakSet 字典 Map Map 的属性 constructor size 操作 ...

最新文章

  1. 【转】推荐两款富文本编辑器:NicEdit和Kindeditor
  2. Deconvolution与Upsampling的区别
  3. 【Linux】FrameBuffer操作入门
  4. 完美解决你使用eclipse编辑jsp、js文件时,经常出现卡死的问题
  5. how is my real odata request hijacked by Mock server
  6. 求二叉树的深度和宽度
  7. python3.6字典有序_为什么从Python 3.6开始字典有序并效率更高
  8. java中链式调用_Java及Android中常用链式调用写法简单示例
  9. 一个分布式服务器集群架构方案
  10. 位置2的索引超出数组范围不能超过10_golang学习笔记--切片slice 与数组 arr
  11. [转]编译器选项(摘自MSDN)及VC项目配置基础
  12. BeanFactory容器的设计原理
  13. React Native三端融合在沪江的应用实践
  14. token干什么用_什么是token
  15. 口述实录:丁磊汪延张朝阳怎么请人吃饭拉单[凤凰网]
  16. 【最优方案】合唱队形
  17. 【托业】【金山词霸】单词1-20
  18. 安科瑞电气火灾监控系统对分散在建筑内的探测器进行遥测、遥调、遥控、遥信,方便实现监控与管理。
  19. [hdu 6355] Fireflies
  20. ArcGIS 栅格计算器 Con用法

热门文章

  1. 《开源硬件创客——15个酷应用玩转树莓派》——第1章 初识树莓派
  2. JDK 8的一些新特性
  3. [MySQL Reference Manual] 24 MySQL sys框架
  4. mysql GRANT
  5. Moses manual 中Basline System 2.3.4节用IRSTLM创建语言模型的命令有误
  6. 社会计算:服务群体社会的大数据科学
  7. PSPad 免费文本编辑器推荐
  8. ActiveMQ死信产生的原因及使用方案
  9. hive 把mysql语句执行_R分别连接mysql hive执行操作
  10. LAMP架构mariadb/apache的安装及基本使用