Set和Map 数据结构
Set和Map是数据结构,不是数据类型ES6 提供了新的数据结构
Set。它类似于数组,但Set里的值都是唯一的Set本身是一个构造函数,用来生成Set 数据结构
Set的实例(myset)的属性和方法- 属性
myset.size:返回 Set 结构的成员总数
 - 方法
myset.add(val):添加某个值,返回 Set 结构本身myset.delete(val):删除某个值,返回一个布尔值,表示删除是否成功myset.has(val):返回一个布尔值,表示该值是否为Set的成员myset.clear():清除所有成员,没有返回值myset.forEach((val, key, set) => {}):使用回调函数遍历每个成员- 第一二个的参数
val 和 key是一样的,set是set集合本身 
- 第一二个的参数
 myset.keys():返回键名的遍历器myset.values():返回键值的遍历器myset.entries():返回键值对的遍历器 ```javascript // 案例一 const myset = new Set();
 
- 属性
 
let s1 = Symbol();
// 增加元素 myset.add(1); myset.add(1); // 重复了,自动过滤 myset.add({}).add(s1); console.log(myset.size); // 3
// 删除元素 myset.delete(1); console.log(myset.has(s1)); // true
// 清空元素 myset.clear();
```javascript// 案例二:new Set() 如何传参// 参数是带有[Symbol.iterator]属性的对象即可let s1 = new Set([4, 5, 6]);let s2 = new Set(document.childNodes);(function () {let s3 = new Set(arguments);})(4, 5, 6)
// 案例三:关于set的遍历let set = new Set(['red', 'green', 'blue']);for (let item of set.keys()) {console.log(item);}// red// green// bluefor (let item of set.values()) {console.log(item);}// red// green// bluefor (let item of set.entries()) {console.log(item);}// ["red", "red"]// ["green", "green"]// ["blue", "blue"]// Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法Set.prototype[Symbol.iterator] === Set.prototype.values // true// 所以有for (let item of set) {console.log(item)}// red// green// blue
Set的简单应用
// 数组去重let arr = [1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 7];arr = [...new Set(arr)]; // [1,2,3,4,5,6,7]// 实现交、并、差let a = new Set([1, 2, 3]);let b = new Set([4, 3, 2]);// 交集let intersect = new Set([...a].filter(item => b.has(item)))// 并集let union = new Set([...a, ...b]);// (a 相对于 b 的)差集let difference = new Set([...a].filter(item => !b.has(item)))
WeakSet
- WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别
- WeakSet 的成员只能是对象,不能是其他类型的值
 - WeakSet 中的对象(非值类型)都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用
 
 WeakSet的实例(myweakSet)的属性和方法- 属性
myweakSet没有myweakSet.size这个属性
 - 方法
myweakSet.add(val):添加某个值,返回 Set 结构本身myweakSet.delete(val):删除某个值,返回一个布尔值,表示删除是否成功myweakSet.has(val):返回一个布尔值,表示该值是否为Set的成员
 - 应用
- WeakSet 的一个用处,是储存 DOM 节点,而不用担心这些节点从文档移除时,会引发内存泄漏 ```javascript // 案例一:成员只能是对象 let myweakSet = new WeakSet(); let arr = [1, 2, 3]; let obj = { name: ‘foo’ }; let str2 = new String(‘good’); myweakSet.add(arr); // 通过 myweakSet.add(obj); // 通过 myweakSet.add(str1); // 报错 myweakSet.add(str2); // 通过
 
 
- 属性
 
myweakSet.delete(arr)
console.log(myweakSet);
```javascript// 案例二:弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用let myweakSet = new WeakSet();myweakSet.add([1, 2, 3]);myweakSet.add({ name: 'foo' });myweakSet.add(new String('good'));console.log(myweakSet); // 空的Set。[[Entries]]里面什么都没有/*** 由于[1, 2, 3]、{ name: 'foo' }、new String('good')* 没有像案例一,赋值给一个变量,没有被某个变量引用* 执行完add函数后,由于没有被变量引用。浏览器的垃圾回收机制又不考虑WeakSet的引用* 根据浏览器的垃圾回收机制,内存被回收了* 所以myweakSet里面的东西,就找不到了*/
Map
Map的介绍
- ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键
- 如果需要“键值对”的数据结构,Map 比 Object 更合适
 
 Map的实例(myMap)的属性和方法- 属性
myMap.size:返回 Map 结构的成员总数
 - 方法
myMap.set(key,value):该方法设置键名key对应的键值为value,然后返回整个 Map 结构- 如果key已经有值,则键值会被更新,否则就新生成该键
 
myMap.get(key):该方法读取key对应的键值,如果找不到key,返回undefinedmyMap.has(key):该方法返回一个布尔值,表示某个键是否在当前 Map 对象之中myMap.delete(key):该方法删除某个键,返回true。如果删除失败,返回falsemyMap.clear():该方法清除所有成员,没有返回值myMap.keys():返回键名的遍历器myMap.values():返回键值的遍历器myMap.entries():返回所有成员的遍历器myMap.forEach():遍历 Map 的所有成员 ```javascript // 案例一 let myMap = new Map();
 
- 属性
 
let obj = { name: 2 }; let sym = Symbol(); // 添加键值对 myMap.set(‘good’, true) myMap.set(obj, { age: 18 }).set(sym, 456);
// 获取key对应value myMap.get(sym); // 456
// 判断是否含有obj这个key myMap.has(obj); // true
// 找到对应的key,删除key-value myMap.delete(sym); // true
console.log(myMap.size); // 2
// 清空所有成员 myMap.clear();
console.log(myMap.size); // 0
```javascript// 案例二:new Map() 如何传参// 参数可以是任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构// 传参:数组let m1 = new Map([[{ name: 'Kery' }, { age: 18 }],[456, 'good-one'],[Symbol(), 'pointSystem']])// 传参:set集合let set = new Set();document.head.childNodes.forEach((item, index) => set.add([index, item]))let m2 = new Map(set);// 传参:map集合let m3 = new Map(m1);
// 案例三:关于Map的遍历let map = new Map([[1, 55],['good', 123],[{}, 555]])
Map数据结构与其他数据结构的互相转换
- Map 与 数组 ```javascript // 数组 转 Map let map = new Map([ [1, 55], [‘good’, 123], [{}, 555] ])
 
// Map 转 数组 let arr = […map]; // [[1, 55], [‘good, 123], [{}, 555]]
- Map 与 对象```javascript// 对象 转为 Map// 可以通过Object.entries()let obj = { a: 1, b: 2 };let map = new Map(Object.entries(obj));// Map 转为 对象function strMapToObj(strMap) {let obj = Object.create(null);for (let [k,v] of strMap) {obj[k] = v;}return obj;}let obj2 = strMapToObj(map);
- Map 与 JSON
- Map 转 JSON
- 一种情况是,Map 的键名都是字符串,这时可以选择转为对象 JSON。
 - 另一种情况是,Map 的键名有非字符串,这时可以选择转为数组 JSON
 
 - JSON 转 Map
- 一种情况是,所有键名都是字符串
 - 另一种情况是,整个 JSON 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组 ```javascript // JSON 转成 Map let json1 = JSON.stringify({ a: [456], b: 2 }); let json2 = JSON.stringify([[true, 123], [{ foo: 3 }, [‘abc’]]]);
 
 
 - Map 转 JSON
 
function jsonToMap(json) { let tmp = JSON.parse(json); let type = Object.prototype.toString.call(tmp).slice(8, -1); let map = null; if (type === ‘Object’) { map = new Map(Object.entries(tmp)); } else if (type === ‘Array’) { map = new Map(tmp); } return map }
let map = jsonToMap(json1);
// Map 转 JSON let map1 = new Map([ [‘a’, 123], [13, { name: ‘jack’ }] ]);
let map2 = new Map([ [new Date(), 1], [{ age: 18 }, 55], [Symbol(), 66] ])
function mapToJSON(map) { let keys = […map.keys()]; let check = keys.every(key => [‘Number’, ‘String’].includes(Object.prototype.toString.call(key).slice(8, -1)) ) if (check) { let obj = Object.create(null); map.forEach((val, key) => { obj[key] = val }) return JSON.stringify(obj); } return JSON.stringify([…map]); }
let json = mapToJSON(map2); ```
WeakMap
WeakMap结构与Map结构类似,也是用于生成键值对的集合。但,它与**Map**有两个区别- WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名
 - WeakMap 中的对象(非值类型)都是弱引用,即垃圾回收机制不考虑 WeakMap 对该对象的引用
 
WeakMap的实例(myweakMap)的属性和方法- 属性
myweakMap没有myweakMap.size这个属性
 - 方法
myweakMap.set(key, val):添加键值对,返回 Map 结构本身myweakMap.has(key):返回一个布尔值,表示该值是否为Map的成员myweakMap.get(key):返回 key 对应的值myweakMap.delete(key):删除 key 那个键值对
 - 应用
- 是储存 DOM 节点,而不用担心这些节点从文档移除时,会引发内存泄漏
 
 
- 属性
 
