为什么要集合
JS中类集合的东西 对象(Object),纯粹的对象不可遍历。不能使用 for-of
Set
一个Set是一群值的集合,它是可变的,能够增删,但是与数组不同的是Set不包含相同元素
Set的数据存储做了速度优化:
Set支持的操作:
- new Set:创建一个新的、空的 Set。
- new Set(iterable):从任何可遍历数据中提取元素,构造出一个新的集合。
- set.size:获取集合的大小,即其中元素的个数。
- set.has(value):判定集合中是否含有指定元素,返回一个布尔值。
- set.add(value):添加元素。如果与已有重复,则不产生效果。
- set.delete(value):删除元素。如果并不存在,则不产生效果。.add()和.delete()
都会返回集合自身,所以我们可以用链式语法。 - set[Symbol.iterator]():返回一个新的遍历整个集合的迭代器。一般这个方法不会被直接调用,因为实际上就是它使集合能够被遍历,也就是说,我们可以直接写 for (v of set) {...}等等。
- set.forEach(f):直接用代码来解释好了,它就像是 for (let value of set){ f(value, value, set); }的简写,类似于数组的.forEach()方法。
- set.clear():清空集合。
- set.keys()、 set.values()和 set.entries()返回各种迭代器,它们是为了兼容Map 而提供的,所以我们待会儿再来看。
负责构造集合的 new Set(iterable)是唯一一个在整个数据结构层面上操作的。把数组转化为集合,在一行代码内去重;也可以传递一个生成器,函数会逐个遍历它,并把生成的值收录为一个集合;也可以用来复制一个已有的集合。
Map(key-value)
map支持的操作:
- new Map:返回一个新的、空的 Map。
- new Map(pairs):根据所含元素形如[key, value]的数组 pairs 来创建一个新的Map。这里提供的 pairs 可以是一个已有的 Map 对象,可以是一个由二元数组组成的数组,也可以是逐个生成二元数组的一个生成器,等等。
- map.size:返回 Map 中项目的个数。
- map.has(key):测试一个键名是否存在,类似 key in obj。
- map.get(key):返回一个键名对应的值,若键名不存在则返回 undefined,类似obj[key]。
- map.set(key, value):添加一对新的键值对,如果键名已存在就覆盖。
- map.delete(key):按键名删除一项,类似 delete obj[key]。
- map.clear():清空 Map。
- map[Symbol.iterator]():返回遍历所有项的迭代器,每项用一个键和值组成的二元数组表示。
- map.forEach(f) 类似 for (let [key, value] of map) { f(value, key,map); } 。 这 里 诡 异 的 参 数 顺 序 , 和 Set 中 一 样 , 是 对 应 着Array.prototype.forEach()。
- map.keys():返回遍历所有键的迭代器。
- map.values():返回遍历所有值的迭代器。
- map.entries():返回遍历所有项的迭代器,就像 map[Symbol.iterator]()。实际上,它们就是同一个方法,不同名字。
JS与其他函数的不同
一、没有哈希代码的哈希表
这两个 URL 应该按相同处理,毕竟它们有完全一样的属性。但在 JavaScript 中,它们是各自独立、互不相同的,并且,绝对没有办法来重载相等运算符。
二、可预测性
遍历 Map或 Set 的顺序就是其中元素的插入顺序。自定义哈希表的遍历顺序会暴露一些哈希对象的代码,继而引发关于哈希函数实现的一些恼人的安全问题。例如,暴露出的代码绝不能获知一个对象的地址。(向不受信任的 ES 代码透露对象地址而对其自身隐藏,将是互联网的一大安全漏洞。)
WeakMap 和 WeakSet
- WeakMap 只支持 new、 has、 get、 set 和 delete。
- WeakSet 只支持 new、 has、 add 和 delete。
- WeakSet 的值和 WeakMap 的键必须是对象。
三、隐藏垃圾回收的不确定性
一个 WeakSet 并不对其中对象保持强引用。当 WeakSet 中的一个对象被回收时,它会简单地被从 WeakSet 中移除。WeakMap 也类似地不为它的键保持强引用。如果一个键仍被使用,相应的值也就仍被使用。
弱引用暴露了底层垃圾回收的实现细节
本文参考《ES6-In-Depth》