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

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集合)