一、set
    1.es6新数据结构。特点是元素值唯一(键值相等)、会主动去重。判断方法是 ‘值相等’ 原则,不进行隐式转化,NaN与自身相等(类似Object.is)。
    set构造函数,接受一个具有iterator接口的数据结构作为参数如array、map、set、类数组(domlist、arguments、string,map),否则会报错。
    set.size表示集合元素个数(类似于数组length属性)

    1. let mySet = new Set('123123abcabc');
    2. console.log(mySet)
    3. // => Set(6) {"1", "2", "3", "a", "b", …}
    4. [[Entries]]
    5. 0: "1"
    6. 1: "2"
    7. 2: "3"
    8. 3: "a"
    9. 4: "b"
    10. 5: "c"
    11. size: 6
    1. 2.用处:<br />(1)数组去重(**可以对两个NAN去重**)
    1. let arr = [1,1,2,2,'a','a','b','b'];
    2. function unique (arr){
    3. return Array.from(new Set(arr))
    4. }
    5. console.log(unique(arr)) // => [1, 2, "a", "b"]

    (2)字符串去重

    1. let str ='112233445566';
    2. function uniqueStr (str){
    3. return [... new Set(str)].join('')
    4. }
    5. console.log(uniqueStr(str))
    1. 3.set原型方法<br />(1set.prototype.add 添加新元素<br />(2set.prototype.delete 删除元素,返回boolean表示删除是否成功<br />(3set.prototype.has 判断是否包含元素,赶回boolean<br />(4set.prototype.clear 清空所有元素,没有返回值<br />set结构只有增删、判断有无、清空的功能。没有直接改的功能。<br />4.set遍历方法<br />(1set.keys set.values返回相同元素值的遍历器iterator<br />(2set.entries 返回二维数组,数组中包含两个相同的值(set的键与值相同)<br />(3set.forEach 和数组的forEach相同,接受一个两个参数,第一个为callback函数,第二个为函数中的this值。<br />set遍历方法中不能改变原数据,只能重新赋值。数组想要删除的话,用split方法。
    1. let set = new Set([1,2,3]);
    2. function changeSet(set1){
    3. let newSet = new Set([...set1].map(item => item * 2));
    4. console.log(set, newSet)
    5. set = newSet
    6. }
    7. changeSet(set)
    8. console.log(set) // 给形参重新赋值不会影响外部变量,修改形参会因为共享数据而影响外界
    1. 5.set结构转化为数组后可以使用mapfilter等方法,所以能够很方便地得出两个数据结构的并集(union)、交集(intersect)、差集(difference
    1. let set1 = new Set('123abc'),
    2. set2 = new Set('136acf');
    3. let union = new Set([...set1,...set2]),
    4. intersect = new Set([...set1].filter(item => set2.has(item))),
    5. difference = new Set([...set1].filter(item => !set2.has(item)));
    6. console.log(union, intersect, difference)

    二、weakSet
    weakSet也是元素唯一的数据结构,但是元素必须是对象,传对象会报错。

    1. let set = new weakSet([{name:'weakSet'}]);
    1. weakSetaddhasdelete方法。没有clear方法。<br />** weakSet对对象是弱引用**,**不会被垃圾回收机制考虑**,也就是,如果外部不再引用weakSet中的对象,那么该对象会被垃圾回收机制清理。<br />weakSet没有size属性,因为里面的对象随时都可能消失。所以不能进行遍历。<br />用处:<br />(1weakSet可以用来保存dom节点,在dom从文档中删除后,不用担心内存泄漏。<br />(2)给原型添加只能由实例调用的方法
    1. let setWeak = new weakSet()
    2. class weakSetFun {
    3. constructor(){
    4. setWeak.add(this)
    5. }
    6. foo(){
    7. let isInstance = setWeak.has(this);
    8. if(isInstance){
    9. console.log('function called')
    10. }else{
    11. throw new Error('only instance can call this function')
    12. }
    13. }
    14. }

    三、map
    1、基本概念、用法
    js中,object是一种’键值对’的集合,键名只能为字符串,es6中Map突破了这一种束缚,接受任意类型作为键名
    Map构造函数中接受部署Iterator接口的数据结构(array, set, map, nodeList, arguments等),且每个元素为包含两个元素的数组,否则会报错(Iterator value xxx is not an entry object)。

    1. let myMap = new Map([ [[], 'array',], [123, [5,6,7]]]);
    2. console.log(myMap)
    3. let set1 = new Set([[[], 1], [[], 2]]),
    4. map1 = new Map(set1);
    5. console.log(map1)

    map有get、set、delete、clear方法用于存取删除清空元素。
    map.size属性表示,储存元素个数。
    map结构中,键名的重复性判断是值相等,不进行隐式转化( set结构,find,findIndex,includes都是值相等判断,NaN等于自身,0 等于-0 ),如果是引用值,map会判断其引用指针。

    1. let o = {
    2. name:'obj'
    3. },
    4. myMap = new Map();
    5. myMap.set(o, 'name');
    6. console.log(myMap.get(o), myMap.size)
    7. //属性重名会覆盖
    8. myMap.set(NaN,'1')
    9. myMap.set(NaN,'6')
    10. console.log(myMap.get(NaN)) // => '6'
    11. //map判断键名引用值
    12. let map2 = new Map();
    13. map2.set(['a'], 1)
    14. console.log(map2.get(['a'])) // => undefined
    1. 用引用值设置键名,这样就解决了同名属性冲突的问题,在拓展别人的插件时很管用。

    2、map的遍历
    map的遍历顺序就是元素插入顺序,而object是一种无序的键值对集合,es6中新增了有序键值对集合,所以给object部署iterator就没有啥必要了。
    map.keys 返回map元素所有键的迭代器
    map.values 返回map元素所有值的迭代器
    map.entries 返回一个二维数组,每个元素为一个数组,包含了一对键值对元素。
    map.forEach 遍历map的方法

    1. let map = new Map([['1', 1], ['abc', 123]]);
    2. map.forEach((value, key, mapObj)=>{
    3. // 回调函数中形参顺序为value, key, map, 与array的forEach一样value, index, array,
    4. //array的index就是元素的key值
    5. console.log(value, key, mapObj)
    6. },null)
    1. map.entries返回的结构与map[Symbol.iterator]一样,两者相等。
    1. let map = new Map([['1', 1], ['abc', 123]]);
    2. let mapEntiresIterator = map.entries();
    3. console.log(mapEntiresIterator)
    4. console.log(mapEntiresIterator.next())
    5. // => {value: ['1', 1], done: false} value是当前遍历的元素,不是元素的value值
    6. for(let [k, v] of mapEntiresIterator){
    7. console.log(k, v) // => 'abc', 123
    8. }
    1. map转换为数组: 拓展运算,转化后就可以用数组的mapfilter等方法了。<br />过滤map中值小于6的元素。
    1. let map = new Map([[{name:123}, 6], [[],[1]]]);
    2. function transform(map){
    3. let newMap = new Map([...map].filter((item)=> item[1] < 6));
    4. return newMap
    5. }
    6. map = transform(map)
    7. console.log(map)

    四、weakMap
    是一种特殊的map结构,只接受键名为对象元素,对键名元素对象的引用为弱引用,对键值对象为正常引用。
    weakMap的专用场合就是,防止内存泄漏,适合将dom节点拿来作为元素的键名,如果文档中dom节点被删除,weakMap中对应的键名和键值就会自动消失。
    weakMap和weakSet一样,元素随时可能消失,所以没有size属性,没有forEach方法。