关于set和map,你知道多少?
ES6中新增的两种数据结构:Set和Map。这两种结构一个是类数组结构一个是类对象结构,两种结构给JS处理数据的方式带来了不小的改变。
1、Set
这种类数组结构的成员都是惟一的,而且Set结构具有可遍历属性(Iterator)。而且本身作为构造函数,声明Set数据结构,需要用到new操作符。
const set = new Set();
[1,2,1,2,3,3].forEach(x => set.add(x));
for (let i of set) {
console.log(i);
}
// 1,2,3
当然我们也可以直接初始化Set结构:
const set = new Set([1,2,1,2,3,3]);
[...set]
// [1, 2, 3]
很明显,扩展运算符可以将Set结构转化为数组。
那么如果将一个数组去重就可以用Set结构:
let arr =[1,2,3,4,5,1,2];
Array.from(new Set(arr));//[1,2,3,4,5]
或者:
[...new Set(arr)]
对于简单的数值类型,1和‘1’在Set中是两个数值。
1、add()、delete()、has()、clear()方法
上面四种方法对应的操作如下:
set.add(1).add(2).add(3);
set.size // 3
set.has(1) // true
set.has(2) // true
set.has(4) // false
set.delete(2);
set.has(2) // false
set.clear() //清除所有的值
2、keys(),values(),entries() 方法
上面三种对应Set的遍历方法,细心地朋友会发现这和数组与对象的遍历是对应的:
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转化为数组。
2、Map
Map类似于对象,是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。这比Object对象更强大。Map结构以键作为唯一性,如果你加入了两个相同的键,那么后者会覆盖前者
同样的与Set操作相似:
const map = new Map();
const o = {p: 'Hello World'};
map.set(o, 'content')
map.get(o) // "content"
map.has(o) // true
map.delete(o) // true
map.has(o) // false
可以看出Map也具有和Set相同的方法。
ES6规定:任何具有可遍历属性的结构都可以当做Map的构造参数用来生成map结构,当把一个类数组作为参数时:
const set = new Set([
['foo', 1],
['bar', 2]
]);
const m1 = new Map(set);
m1.get('foo') // 1
const m2 = new Map([['baz', 3]]);
const m3 = new Map(m2);
m3.get('baz') // 3
可以看出,参数除了是具有可遍历属性,而且要以键值对的形式出现。
Map的遍历操作与Set一致。
当你试图将一个Map结构变为数组时:
const map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
[...map.keys()]
// [1, 2, 3]
[...map.values()]
// ['one', 'two', 'three']
[...map.entries()]
// [[1,'one'], [2, 'two'], [3, 'three']]
[...map]
// [[1,'one'], [2, 'two'], [3, 'three']]
当然还有weakSet与weakMap,就留到以后再说。