介绍下Set、Map、WeakSet和WeakMap?

595 阅读5分钟

原文链接 github.com

ES6提供了新的数据机构: Set、WeakSep、Map和WeakMap。

Set

数据结构Set类型数组,但是没有重复值,值都是唯一的,值可以任何类型。 Set本身是构造函数,可以通过new直接创建对应的结构。

const set = new Set();
// or 传入初始化数组
const set1 = new Set([1,2,3])
// or 传入具有 iterable 接口的其他数据结构
const set2 = new Set(document.querySelectorAll('div'));

由于Set数据结构中的元素是不重复的,所以可以用来作为数组去重的方式

[...new Set(array)]

属性和方法

属性

  • Set.prototype.constructor:构造函数,默认就是Set函数。
  • Set.prototype.size:返回Set实例的成员总数。

方法

  1. 操作函数
  • Set.prototype.add(value):添加某个值,返回 Set 结构本身。
  • Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
  • Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。
  • Set.prototype.clear():清除所有成员,没有返回值
const set = new Set();

// 由于add方法返回的是Set结构本身,所以可以连续操作
set.add(1).add(3);
  1. 遍历函数
- Set.prototype.keys():返回键名的遍历器
- Set.prototype.values():返回键值的遍历器
- Set.prototype.entries():返回键值对的遍历器
- Set.prototype.forEach():使用回调函数遍历每个成员

WeakSet

数据结构WeakSet与Set类型,没有重复值,值也是唯一的,但是成员只能是对象,而不能是其他类型的值。

对于WeakSet的细节介绍,阮一峰老师已经解说的很详细了,这边没补充,就直接引用了,有需要可查看原文

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

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

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

属性和方法

属性

  • WeakSet.prototype.constructor:构造函数,默认就是WeakSet函数。

方法

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

Map

数据结构Map与Object类型,本质上是键值对的集合(Hash结构); Map数据结构的出现主要是为了解决原有的Object对象的键只能是字符串的局限; Map的”键“支持各种类型的结构;

属性和方法

属性

  • Map.prototype.constructor:构造函数,默认就是Map函数。
  • Map.prototype.size:返回Map实例的成员总数。。

方法

  1. 操作方法
  • Map.prototype.set(key, value):设置健值,后添加的会覆盖前添加的value。
  • Map.prototype.get(key):获取对应的健值,不存在则返回 undefined。
  • Map.prototype.has(key):判断某个键是否在当前 Map 对象之中。
  • Map.prototype.delete(key);返回布尔值,表示是否删除成功。
  • Map.prototype.clear();清除所有成员,没有返回值。
  1. 遍历方法
  • Map.prototype.keys():返回键名的遍历器。
  • Map.prototype.values():返回键值的遍历器。
  • Map.prototype.entries():返回所有成员的遍历器。
  • Map.prototype.forEach():遍历 Map 的所有成员。

WeakMap

WeakMap结构与Map结构类似,也是用于生成键值对的集合; WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名; WeakMap的键名所指向的对象,不计入垃圾回收机制;

属性和方法

属性

  • WeakMap.prototype.constructor:构造函数,默认就是WeakMap函数。

方法

  1. 操作方法
  • Map.prototype.set(key, value):设置健值,后添加的会覆盖前添加的value。
  • Map.prototype.get(key):获取对应的健值,不存在则返回 undefined。
  • Map.prototype.has(key):判断某个键是否在当前 WeakMap 对象之中。
  • Map.prototype.delete(key);返回布尔值,表示是否删除成功。
  1. 遍历方法 无

总结

总结下Set、Map、WeakSet和WeakMap的区别

  • Set - 对象允许存储任何类型的唯一值,无论是原始值还是对象引用;
  • WeakSet - 成员都是对象;成员都是弱引用,可以被垃圾回收机制回收,可以用来保存DOM节点,不容易造成内存泄露;
  • Map - 本质上是键值对的集合,类似集合;可以遍历,可以和各种数据格式转换;
  • WeakMap - 只接受对象作为键名(null除外),不接受其他类型的值作为键名;键名是弱引用,健值可以是任意的,键名所指向的对象可以被垃圾回收,此时健名无效的;不能遍历;

参考资料

Set 和 Map 数据结构