ES6-6.Set集合和Map集合

一、Set集合

Set集合是一种包含多多个重复值的无序列表,可以快速访问其中的数据,更有效的追踪各种离散值
1、创建Set集合并添加元素

    //由于在set集合中,不会对所存值进行强制的类型转换,所以数字5和字符串'5'可以作为独立的元素存在
    let set = new Set();
    set.add(5);
    set.add('5');
    console.log(set.size);       //2  

    //因为不会强制转换,所以可以添加多个对象
    let set = new Set(),
        key1 = {},
        key2 = {};
    set.add(key1);    
    set.add(key2);
    console.log(set.size);      //2

    //当多次调用add()方法,并且添加相同的值时,Set集合只会添加一次
    let set  = new Set();
    set.add(5);   
    set.add('5');   
    set.add(5);        //此次的add忽略
    console.log(set.size);       //2

2、has(),delete(),clear()方法

has()方法判断Set集合是否存在某个值

delete()方法删除Set集合中的某一个元素

clear()方法移除集合中的所有元素

3、Set集合的forEach()方法

    //使用forEach()方法迭代输出Set集合中每一个元素
    // forEach()方法有三个参数
    // 1、Set集合中下一次索引的位置;
    // 2、与第一个参数一样的值;
    // 3、被遍历的Set集合本身
    
    let set = new Set([1,2]);
    set.forEach(function(value, key, ownerSet){
        console.log(key + "" + value);
        console.log(ownerSet === set);

    });
    //回调函数每次执行,输出的键和值都保持一致,ownerSet永远与set相等,输出内容如下
    // 1 1
    // true
    // 2 2
    // true

forEach回调中如果要使用this,就需要把this传入进去,但如果使用箭头函数则无需传入,如下面的代码:

    // 不使用箭头函数,则需要传入this
    // 这里forEach方法,只需要第一个参数value

    let set = new Set([1, 2]);
    let processor = {
        output(value){
            console.log(value);
        },
        //将this传入作为回调函数的this值,从而this.output()方法可以正确地调用到processor.output()方法
        //如果不传入this,则会报错
        process(dataSet){
            dataSet.forEach(function(value){
                this.output(value);
            }, this)
        }
    };

    processor.process(set);     // 1,2

    //使用箭头函数则无需传入this

    let set = new Set([1,2]);
    let processor = {
        output(value){
            console.log(value);
        },
        process(dataSet){
            //箭头函数从外围process()函数读取this值,这个this指向processor对象
            dataSet.forEach(value => this.output(value));
        }
    };

    processor.process(set);      //1, 2

4、将Set集合转换成数组

    let set = new Set([1, 2, 3, 3, 3, 4, 5]),
        array = [...set];

    console.log(array);     //[1,2,3,4,5]

    //使用这个特性,可以复制一个数组,并且返回一个无重复的新数组

    function eliminateDuplicates(items){
        return [...new Set(items)];
    };

    let numbers = [1, 2, 3, 3, 3, 4, 5],
        noDuplicates = eliminateDuplicates(numbers);

    console.log(noDuplicates);    //[1,2,3,4,5]

5、Weak Set集合
用Set集合保存的变量和对象,即使初始对象被回收或者释放,但是Set集合中一样存在,例如下面的代码:

    let set = new Set(),
        key = {};

    set.add(key);
    console.log(set.size);     //1

    //移除原始引用,但是Set集合还保留了这个引用
    key = null;
    console.log(set.size);     //输出还是1
    
    //重新获取原始引用,你任然可以使用展开运算符将Set集合转换成数组格式并从数组的首个元素取出该引用
    key = [...set][0];

所以有时候,当我们把原始引用清楚的时候,也希望Set集合也会被垃圾回收机制回收掉。这个时候就可以使用Weak Set集合,当原始引用被设置成null,清除的时候,Weak Set集合就会被垃圾回收机制也回收掉。

Weak Set初始化和Set是一样,支持add(),has(),delete()方法。但是有几点要注意:

Weak Set集合不支持传入非对象参数,会报错。

Weak Set集合不可迭代,所以不能用for-of循环。

Weak Set集合不暴露任何迭代器。

Weak Set集合不支持forEach()方法。

Weak Set集合不支持size属性。

所以当你只需要跟踪对象引用,你更应该使用Weak Set集合而不是普通的Set集合。

二、Map集合

Map是一种存储许多键值对的有序列表,其中的键名和对应的值支持所有的数据类型。所以当键名分别为5和"5"时,这是一个两个独立的键。并不会像对象一样,强制转化成字符串。

1、初始化和添加

   let map = new Map();
    map.set('title', 'Understanding ECMAScript6');
    map.set('year', '2016');

    console.log(map.get('title'));     //Understanding ECMAScript6
    console.log(map.get('year'));      //2016
    
    //同样,Map可以用于对象作为键
    let map = new Map(),
        key1 = {},
        key2= {};

    map.set(key1, 5);
    map.set(key2, 42);

    console.log(map.get(key1));     //5
    console.log(map.get(key2));     //42

2、支持的方法

has(key) 检测指定的键名在Map集合中是否已经存在

delete(key) 从Map集合中移除指定键名以及其对应的值

clear() 移除Map集合中的所有键值对

3、Map集合的初始化方法
可以传入数组初始化,例如:

    let map = new Map([['name, Nicholas'], ['age, 25']]);
    
    console.log(map.has('name'));      //true
    console.log(map.get('name'));      //'Nicholas'
    console.log(map.has('age'));       //true
    console.log(map.get('age'));       //25
    console.log(map.size);             //2

4、Map集合的forEach()方法
和Set集合的forEach方法相似,例如:

    let map = new Map([['name',  'Nicholas'], ['age', 25]]);

    map.forEach(function(value, key, ownerMap){
        console.log(key + '' + value);
        console.log(ownerMap === map);      
    });

    // name 'Nicholas'
    // true
    //age  25
    //true

5、Weak Map集合
Weak Map集合中的键名必须是一个对象,如果使用非对象键名会报错。

Weak Map集合最大的用途就是保存Web页面中的Dom元素。一些库如果自定义一些Dom元素,则可以使用Weak Map集合来保存。

支持的方法:has(),delete(),clear()

上一篇:ES6相关


下一篇:ES6模板字符串