一、Set
ES6提供了新的数据结构Set(集合)。它类似于数组,但是成员的值都是唯一的,集合实现了iterator接口,所以可以使用扩展运算符和 for…of 进行遍历。
Set的属性和方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| // 创建一个空集合 let s = new Set();
// 创建一个非空集合 let s1 = new Set([1,2,3,1,2,3]);
// 返回集合的元素个数 console.log(s1.size); // 3
// 添加新元素 console.log(s1.add(4)); // {1,2,3,4}
// 删除元素 console.log(s1.delete(1)); //true
// 检测是否存在某个值 console.log(s1.has(2)); // true
// 清空集合 console.log(s1.clear()); //undefined
|
由于集合中元素的唯一性,所以在实际应用中,可以使用set来实现数组去重:
1 2
| let arr = [1,2,3,2,1] Array.from(new Set(arr)) // {1, 2, 3}
|
可以通过set来求两个数组的交集和并集:
1 2 3 4 5
| // 模拟求交集 let intersection = new Set([...set1].filter(x => set2.has(x)));
// 模拟求差集 let difference = new Set([...set1].filter(x => !set2.has(x)));
|
用以下方法可以进行数组与集合的相互转化:
1 2 3 4 5 6
| // Set集合转化为数组 const arr = [...mySet] const arr = Array.from(mySet)
// 数组转化为Set集合 const mySet = new Set(arr)
|
二、Map
ES6提供了Map数据结构,它类似于对象,也是键值队的集合,但是它的键值的范围不限于字符串,可以是任何类型(包括对象)的值,也就是说, Object 结构提供了“ 字符串—值” 的对应, Map 结构提供了“ 值—值” 的对应, 是一种更完善的 Hash 结构实现。如果需要“ 键值对” 的数据结构, Map 比 Object 更合适。Map也实现了iterator接口,所以可以使用扩展运算符和 for…of 进行遍历。
Map的属性和方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| // 创建一个空 map let m = new Map();
// 创建一个非空 map let m2 = new Map([ ['name', 'hello'], ]);
// 获取映射元素的个数 console.log(m2.size); // 1
// 添加映射值 console.log(m2.set('age', 6)); // {"name" => "hello", "age" => 6}
// 获取映射值 console.log(m2.get('age')); // 6
// 检测是否有该映射 console.log(m2.has('age')); // true
// 清除 console.log(m2.clear()); // undefined
|
需要注意, 只有对同一个对象的引用, Map 结构才将其视为同一个键:
1 2 3
| let map = new Map(); map.set(['a'], 555); map.get(['a']) // undefined
|
上面代码的set和get方法, 表面是针对同一个键, 但实际上这是两个值, 内存地址是不一样的, 因此get方法无法读取该键, 所以会返回undefined。
由上可知, Map 的键实际上是跟内存地址绑定的, 只要内存地址不一样, 就视为两个键。这就解决了同名属性碰撞( clash) 的问题,在扩展库时, 如果使用对象作为键名, 就不用担心自己的属性与原来的属性同名。
如果 Map 的键是一个简单类型的值( 数字、 字符串、 布尔值), 则只要两个值严格相等, Map 将其视为一个键, 包括0和 - 0。另外, 虽然NaN不严格相等于自身, 但 Map 将其视为同一个键。
1 2 3 4 5 6 7
| let map = new Map();
map.set(NaN, 123); map.get(NaN) // 123
map.set(-0, 123); map.get(+0) // 123
|