一、Set
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
1、创建Set集合并添加元素
通过new Set()创建Set集合,调用add方法添加元素
size属性:获取集合中目前的元素数量
let set = new Set();
set.add(5);
set.add("5");
set.add(5);
console.log(set.size);//2
在Set集合中,不会对所存值进行强制的类型转换。数字5和字符串”5”作为两个独立元素存在。第二次传入的数字5是一个重复值,因此不会被添加到集合中。
let set1 = new Set();
let key1 = {}, key2 = {};
set.add(key1);
set.add(key2);
console.log(set1.size);//2 key1和key2不会转成字符串
也可以用传入数组的方式初始化Set:
let set2 = new Set([1, 4, 5, 4, 1, 2, 4, 1]);
console.log(set2.size); //4
2、has 检测set集合中是否存在某个值
console.log(set2.has(4));//true
console.log(set2.has(9));//false
3、delete 移除set集合中的某一个值
set2.delete(4);
console.log(set2.has(4));//false
4、clear 移除集合中的所有元素
set2.clear();
console.log(set2.size);//0
5、forEach 方法
Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。
//forEach 方法 参数1:键名 2:键值 3:被遍历的set集合本身
// Set 结构的键名就是键值(两者是同一个值)
let set3 = new Set([1, 4, 5, 6, "4", "1"]);
set3.forEach((item, i, set) => console.log(item + " " + i));
//1 1
//4 4
//5 5
//6 6
//4 4
//1 1
利用扩展运算符可以将Set集合转成数组
//将set集合转成数组
let arrSet = [...set3];
console.log(arrSet);//[1, 4, 5, 6, "4", "1"]
扩展运算符和 Set 结构相结合,就可以实现数组去重
let arr = [3, 5, 2, 2, 5, 5];
let unique = [...new Set(arr)];
// [3, 5, 2]
ES6中还提出了WeakSet集合:
1)只能用于存储对象,不能存储原始值
2)WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
3)没有size属性和forEach方法
let wSet = new WeakSet(),
key = {};
wSet.add(key);
console.log(wSet.has(key));//true
二、Map
在对象中,对象的属性名总是会被强制转换成字符串类型,但是有时我们并不希望它发生转换。ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。键名的等价判断是通过Object.is()方法实现的,所以数字5与字符串”5”会被判定为两种类型,可以分别作为两个独立的键出现。
通过new Map()创建Map集合,
调用set方法添加元素 set(键名,键值)
从集合中获取信息 get(键名)
size属性:获取集合中键值对数量
let map = new Map();
map.set('year', 2018);
map.set('month', 9);
console.log(map.get('year'));//2018
console.log(map.get('cur'));//undefined
//对象也可以作为键名
let key1 = {}, key2 = {};
map.set(key1, 4);
map.set(key2, 5);
console.log(map.get(key1));//4
console.log(map.get(key2));//5
console.log(map.size);//4
也可以用数组方法初始化Map:
//初始化方式: 传入二维数组,子数组里包含一个键值对的键名与值两个元素
let map1 = new Map([['year', 2018], ['month', 9]]);
console.log(map1.has('year'));//true
console.log(map1.get('month'));//9
console.log(map1.size);//2
Map集合也支持如下方法:
1)has(key):检测指定的键名在Map集合中是否已存在
2)delete(key):从Map集合中移除指定的键名及其对应的值
3)clear():移除Map集合中的所有键值对
4)forEach方法
console.log(map.size);//4
console.log(map.has('month'));//true
console.log(map.delete('month'));//true
console.log(map.has('month'));//false
console.log(map.size);//3
console.log(map.delete('cur'));//删除不存在的 返回false
map.clear();
console.log(map.size);//0
forEach方法的三个参数分别为:键值、键名、map集合本身
//forEach方法 第一个参数:值 第二个参数:键名 第三个参数:map集合本身
map1.forEach((value, key, map1) => console.log(key + " " + value));
//year 2018
//month 9
Map也存在对应的WeakMap:
1)弱引用map集合,只能用非null类型的对象作为键名
2)如果在键名弱引用之外不存在其他的强引用,引擎的垃圾回收机制会自动回收这个引用,同时也会移除weak map集合中的键值对
3)只有set get has delete 方法,不能clear,不能枚举,不支持size属性
let wMap = new WeakMap(),
wkey1 = {},
wkey2 = {};
wMap.set(wkey1, 4);
wMap.set(wkey2, 5);
console.log(wMap.has(wkey1));//true
console.log(wMap.get(wkey1));//4
wMap.delete(wkey1);
console.log(wMap.has(wkey1));//false
console.log(wMap.size);//undefined