Set
Set和数组类似,但是其中的成员都是唯一的,重复的值无法向Set数据结构添加。使用Set
构造函数来创建一个Set
数据结构,可以接受一个数组(或者具有iterable接口的数据结构)作为参数来初始化。
let s = new Set([1,2,3,4,2])
for (let i of s) {
console.log(i)
}
// 1
// 2
// 3
// 4
s.size // 4 返回Set中成员的总数
Set实例的操作方法
add(value)
添加一个成员,返回实例本身delete(value)
删除某个成员,返回一个Boolean,表示是否删除成功has(value)
是否有某个值,返回一个Booleanclear()
清除所有成员let s = new Set()
s.add(1) // Set(1){1}
s.add(2) // Set(2){1,2}
s.delete(1) // true
s.has(1) // false
s.has(2) // true
s.clear() // s => Set(0){}
Set实例的遍历方法
keys()
、values()
、entries()
都是返回一个遍历器对象。Set被认为是不存在键,所以 遍历keys和values返回的对象时得到的值相同。 看一下例子就懂了。 ```javascript let set = new Set([‘red’, ‘green’, ‘blue’]);
for (let item of set.keys()) { console.log(item); } // red // green // blue
for (let item of set.values()) { console.log(item); } // red // green // blue
for (let item of set.entries()) { console.log(item); } // [“red”, “red”] // [“green”, “green”] // [“blue”, “blue”]
事实上,Set结构本身就是可遍历的,且Set.prototype上的迭代器和 Set.prototype.values相同
```javascript
Set.prototype[Symbol.iterator] === Set.prototype.values
// 所以Set的遍历方法暂时还不知道有啥用[doge]
for(let i of new Set([1,2,4])){
// 和上面得到的结果一样
}
forEach
和数组的forEach类似,接受一个回调函数作为参数,回调函数接受三个参数:键值,键名,集合本身。除了回调函数还可以接受一个函数内部this指向的参数。
:::info
向Set中添加元素时,不会发生隐式类型转换,即1 和 “1”是不同的。Set内部使用一个算法判断两个成员是否相同,类似于 “===”,不同的是,认为两个NaN是相同的。
:::
WeakSet
WeakSet和set类似,也是不重复成员的集合,但是顾名思义,weak,弱引用,有如下特点:
- WeakSet中的成员必须是对象
- WeakSet中的对对象都是弱引用,即对对象的引用只剩下WeakSet时,会被垃圾回收机制gc掉
- WeakSet没有遍历的方法也没有size属性。因为是弱引用,对象可能随时会被gc掉,所以不提供遍历的方法和clear方法以及size属性
Map
传统JavaScript对象只能使用字符串作为键值,使用对象作为键值会先将其转换为字符串。可是不可避免的有想要用对象作为键值的场景,所以出现了Map
。Map类似传统的JavaScript对象,不过可以使用对象作为键值。可以使用一个数组(数组的每一项都是key,value的二元数组)作为 new Map()
的初始化参数。
let map = new Map([
['a',1],
[{}, 1]
])
// Map 这个数据结构也拥有iterable接口,可以使用数组扩展运算符展开为数组,得到的就和初始化它的数组参数一样
[...map] // => [['a',1], [{}, 1]]
// 对象扩展运算符得到的是空对象
{...map} // => {}