美文网首页
【ES6 笔记】Set集合与Map集合

【ES6 笔记】Set集合与Map集合

作者: ___Jing___ | 来源:发表于2018-11-02 17:44 被阅读0次

    Set 集合是一种无重复元素的列表,开发者们一般不会像访问数组元素那样逐一访问每个元素,通常的做法是检测给定的值在某个集合中是否存在。Map 集合内含多组键值对,集合中每个元素分别存放着可访问的键名和它对应的值,Map 集合经常被用于缓存频繁取用的数据。

    ES6中的 Set 集合

    Set 类型时一种有序列表,其中包含一些相互独立的非重复值,通过Set结合可以快速访问其中的数据,更可有效地追踪各种离散值。

    • 创建 Set 集合并添加元素
    let set = new Set(); //创建Set集合
        set.add(5);
        set.add('5');
    console.log(set.size); // 2
    /*
    * 在Set集合中,不会对所有值进行强制的类型转换,数字5和字符串“5”可以作为 
      两个独立的元素存在,
    * 唯一列外的是,Set集合中的+0和-0被认为是相等的。
    */
    
    let set = new Set(),
        key1 = {} ,
        key2 = {}; 
        set.add(key1);
        set.add(key2); 
    console.log(set.size); //2
    /*
    * 由于key1和key2不会被转为字符串,他们是两个独立的地址引用,因而他们在Set集合中是两个独立的元素。
    */
    
    let set = new Set();
        set.add(5);
        set.add('5');
        set.add(5);
    console.log(set.size); //2
    
    let constructorSet = new Set([1,2,3,4,5,5,5,5,5,5,5]);
    console.log(constructorSet.size); //5
    /*
    * 由于第二次传入的数字5是一个重复值,因此不会被添加到集合中。
    * Set集合会过滤掉重复的值从而保证集合中的元素各自唯一。
    */
    
    • 通过has()方法检测Set集合中是否存在某个值
    let set = new Set();
    set.add(5);
    console.log(set.has(5)); //true
    console.log(set.has(99)); // false
    
    • 移除元素
    let set = new Set();
    
        set.add(6);
        set.add(5);
    
        console.log(set.has(5));  // true
    
        set.delete(5); //删除指定元素
    
        console.log(set.has(5)); //false
        console.log(set.size);  //1
    
        set.clear();  //清空set合集中的所有元素
    
        console.log(set.has(6));  //false
        console.log(set.size);  // 0
        
    
    • Set 集合中的forEach(callback, this)方法
      forEach()方法接受一下3个参数:
      1. value 当前值
      2. key 当前索引值
      3. 被遍历的Set集合本身
    let set = new Set(['a','b']);
    
    set.forEach((value,key,selfSet)=>{
          console.log(`Key is ${key} and value  is ${value}`);
          console.log(selfSet == set)
    })
    // Key is a and value  is a
    // true
    // Key is b and value  is b
    // true
    

    如果需要在回调中使用this引用,则可以将它作为第二个参数传入forEach()函数:

    let set = new Set([1,2]);
    let processor = {
        output(value){
            console.log(value)
        },
        process(dataSet){
            dataSet.forEach(function(value){
                  this.output(value)
            },this)
        }
    }
    processor.process(set)
    // 1
    // 2
    
    • 将Set集合转换为数组
    let set = new Set([1,2,3,4,5,5,5,5,5]);
    let array = [...set];
    console.log(array);  // [1,2,3,4,5]
    

    以上过程自动移除了数组中的重复值,利用这个特性,可以创建并赋值一个无重复的数组:

    function eliminateDuplicates(items){
          return [...new Set(items)];
    }
    
    let array = [1,1,1,1,2,2,3,4,5,5,5,5,5,5];
    let noDuplicates = eliminateDuplicates(array);
    
    console.log(noDuplicates);  // [1,2,3,4,5]
    

    Weak Set 集合

    Weak Set 集合只存储对象的弱引用,并且不可以存储原始值;集合中的弱引用如果是对象唯一的引用,则会被回收并释放相应内存。

    • 创建 Weak Set 集合
    let weakSet = new WeakSet();  //创建Weak Set集合
    let key = {};
    
    weakSet.add(key);  //像Weak Set集合中添加对象
    
    console.log(weakSet.has(key)); // true
    
    weakSet.delete(key);  // 删除 Weak Set集合中的key引用
    
    console.log(weakSet.has(key));  //false
    
    let key1 = {};
    let key2 = {};
    let set = new WeakSet([key1, key2]);
    console.log(set.has(key1));  // true
    console.log(set.has(key2));  // true
    /*
    * 向WeakSet构造函数传入一个含有两个对象的数组,最后创建一个包含这两个对象的WeakSet集合
    * WeakSet构造函数不接受任何原始值,如果数组中包含其他非对象值,会抛出错误
    */
    
    • 两种 Set 类型的主要区别
      两种Set类型之间最大的区别是Weak Set保存的是对象之的弱引用:
      1. 在WeakSet的实例中,如果向add()方法传入非对象参数会导致程序报错,而向has()和delete()方法传入非对象参数则会返回false
      2. Weak Set 集合不可迭代,所以不能被用于for-of循环
      3. Weak Set 集合不暴露任何迭代器,所以无法通过程序本身来检测其中的内容
      4. Weak Set 集合不支持forEach()方法
      5. Weak Set 集合不支持size属性

    ES6中的 Map 集合

    ES6中的 Map 类型时一种存储着许多键值对的有序列表,其中的键名和对应的值支持所有的数据类型。键名的等价性判断是通过调用Object.is()方法实现的。

    • 创建 Map 集合
    let  map  = new Map();
    map.set('name','欧阳不乖'); //接受两个参数:key 和 value
    map.set('age',18);  
    
    console.log( map.get('name') );  //'欧阳不乖'
    console.log( map.get('age') );  //18
    console.log( map.get('hobby') );  // undefined 集合中不存在的返回undefined
    
    • Map 集合支持的方法
      1. has(key) 检测指定的键名在Map集合中是否存在
      2. delete(key) 从Map集合中移除指定键名及其对应的值
      3. clear() 移除Map集合中所有的键值对
        Map 集合同样支持size属性,表示当前集合中包含的键值对的数量
    let map = new Map();
    map.set('name','欧阳不乖');
    map.set('age',18);
    
    console.log(map.size);  //2
    
    console.log(map.has('name'));  // true
    console.log(map.get('name'));  // 欧阳不乖
    
    console.log(map.has('age'));  // true
    console.log(map.get('age'));  // 18
    
    map.delete('name');  // 删除name键
    console.log(map.has('name'));  // false
    console.log(map.get('name'));  // undefined
    console.log(map.size);  // 1
    
    map.clear();  //清空所有的集合
    console.log(map.has('age'));  // false
    console.log(map.get('age'));  // undefined
    console.log(map.size);  // 0
    
    • Map 集合的初始化方法
      可以向 Map 构造函数传入数组来初始化一个 Map 集合
    let map = new Map([['name', '欧阳不乖'],['age', 18]]);
    console.log( map.has('name') );  // true
    console.log(map.get('name'));  // 欧阳不乖
    console.log(map.size);  //2
    
    • Map 集合的forEach()方法
      forEach()方法接受一下3个参数:
      1. value 当前值
      2. key 当前索引值
      3. 被遍历的Map集合本身
    let map = new Map([['name', '欧阳不乖'],['age', 18]]);
    map.forEach((value, key, selfMap)=>{
          console.log(`Key is ${key} and value is ${value}`);
          console.log(selfMap==map )
    })
    // Key is name and value is 欧阳不乖
    // true
    // Key is age and value is 18
    // true
    

    Map 集合和 Set 集合很类似,充分理解其中一个,另一个自然就明白了。

    Weak Map 集合

    Weak Map 是弱引 Map 集合,也可用于存储对象的弱引用。Weak Map集合中的键名必须是一个对象,如果使用field对象键名会报错;集合中保存的是这些对象的弱引用,如果弱引用之外不存在其他的强引用,引擎的垃圾回收机制会自动回收这个对象,同时也会移除Weak Map集合中的键值对。

    • 使用Weak Map集合
    let map = new WeakMap();
    let key = {};
    map.set( key, 'Here Is Object Desc');
    
    console.log(map.get(key)); //  Here Is Object Desc
    
    // 移除key元素
    key = null;
    // 此时WeakMap集合为空
    
    • Weak Map集合的初始化方法
      调用 WeakMap构造函数并传入一个数组容器,容器内包含其他数组,每一个数组由两个元素构成:第一个元素是一个键名,传入的值必须是非null的对象;第二个元素是这个键对应的值,可以是任意类型:
    let key1 = {};
    let key2 = {};
    let map = new WeakMap( [ [key1, 'Hello'], [key2, 'World'] ] );
    
    console.log(map.has(key1));  // true
    console.log(map.get(key1));   // Hello
    console.log(map.size ); // undefined
    

    Weak Map 不支持size属性

    • Weak Map集合支持的方法
      1. has(key) 检测指定的键名在Weak Map集合中是否存在
      2. delete(key) 从Weak Map集合中移除指定键名及其对应的值
    let map = new WeakMap();
    let key1 = {};
    let key2 = {};
    map.set(key1,'欧阳不乖');
    map.set(key2,18);
    
    console.log(map.has(key1));  // true
    console.log(map.get(key1));  // '欧阳不乖'
    
    map.delete(key1)
    console.log(map.has(key1));  // false
    console.log(map.get(key1));  // undefined
    
    • Weak Map集合的使用方法及使用限制
      当要在Weak Map 和Map集合之间做出选择时,需要考虑的主要问题是,是否只用对象作为集合的键名,如果是,那么Weak Map集合是最好的选择。

    相关文章

      网友评论

          本文标题:【ES6 笔记】Set集合与Map集合

          本文链接:https://www.haomeiwen.com/subject/rflcxqtx.html