es6 Set和map数据结构

set

  • set构造函数创造相似数组的数据,set数据结构的数据没有重复的值
let ary = [1,2,3,4,4,4,4];
let setData = new Set();
ary.forEach((p) => {
setData.add(p)
})
console.log(setData) // [1,2,3,4]
  • set函数接受一个数组(或者是具备iterable接口的数据类型)做为参数,用来初始化
let setData = new Set([1,2,3,4,4,4,4]);  //  [1,2,3,4]
let setDiv = new Set(document.getElementsByTagName('div'))
  • Set 加入值的时候,不会发生类型转换,例如5和‘5’是不一样的值,NaN和NaN相等的,见代码
let ary = [NaN,NaN,NaN,5,'5',{},{}]
let setData = new Set(ary);// [NaN,5,'5',{},{}]

set实例的属性和方法

  • 属性
    • Set.prototype.constructor:构造函数,默认就是Set函数。
    • Set.prototype.size:返回Set实例的成员总数。
  • 方法
    • add(),向该set数据中加目标值,返回该set
    • has(),判断该set是否包含目标值,返回布尔值,表示是否包含
    • delete(),删除该set的目标值,返回boolean值,表示是否删除成功
    • clear(),清除该set的全部的项,没有返回值
    • Array.from方法能够将set数据转化成数组
// 数组去重
let ary = [1,2,3,3,3,3];
let setData = new Set(ary);
ary =Array.from(setData);

// 结合扩展运算符
let arr = [1,2,3,3,3,3];
let unique = [...new Set(arr)];
  • 遍历操做
    • keys():返回键名的遍历器
    • values():返回键值的遍历器
    • entries():返回键值对的遍历器
    • forEach():使用回调函数遍历每一个成员
    • Set 结构没有键名,只有键值(或者说键名和键值是同一个值),因此keys方法和values方法的行为彻底一致
  • 扩展运算符(...)内部使用for...of循环,因此set数据也可使用扩展运算符
    • 数组的map和filter也能够间接用于set数据,先将set数据转化成数组,在使用map等数组方法数组

    • 因此set很容易实现交并差集数据结构

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);

// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}

// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}

// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}

weakSet数据结构

  • 特性
    • weakSet数据和set数据相似,可是weakSet的成员只能是对象
    • weakSet的成员对象是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,若是其余对象都再也不引用该对象, 那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中
    • 不可遍历,forEach,size都没有
  • 方法
    • WeakSet.prototype.add(value):向 WeakSet 实例添加一个新成员。
    • WeakSet.prototype.delete(value):清除 WeakSet 实例的指定成员。
    • WeakSet.prototype.has(value):返回一个布尔值,表示某个值是否在

map数据类型

  • 特性:
    • Object对象的数据结构是键值对的形式,键是字符串,而map结构的数据能够是‘值-值’的形式,对象也能够作键
    • 参数:
      • 任何具备 Iterator 接口、且每一个成员都是一个双元素的数组的数据结构均可以看成Map构造函数的参数,见例子:
      let mapData = new Map([
      ['name','zhan']  //双元素
      ]);
      mapData.get('name') // 'zhan'
    • 针对同一个键进行赋值,后面的赋值操做会覆盖前面的值
    let mapData = new Map();
     mapData.set('name', 'zhan').set('name', 'hui');
     mapData.get('name'); //'hui'
    • 获取没有设置的键值,返回undefined
    let mapData = new Map().get('name'); // undefined
    • 注意
      • 只用引用类型的数据做为键时,由于不一样的对象对应的内存地址不同, 因此对应的值也就不一样,其实Map数据的键是和内存地址作绑定的,这一点须要格外注意
      //下面两个对象对应的内存地址不一样,
      let mapData = new Map();
      mapData.set({},'zhan');
      mapData.get({}); //undefined
      • Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,好比0和-0就是一个键, 布尔值true和字符串true则是两个不一样的键。另外,undefined和null也是两个不一样的键。虽然NaN不严格相等于自身,但 Map 将其视为同一个键。
      let map = new Map();
      
      map.set(-0, 123);
      map.get(+0) // 123
      
      map.set(true, 1);
      map.set('true', 2);
      map.get(true) // 1
      
      map.set(undefined, 3);
      map.set(null, 4);
      map.get(undefined) // 3
      
      map.set(NaN, 123);
      map.get(NaN) // 123
  • Map实例的属性和操做方法
    • size,返回map数据的成员个数
    • set()
    • get()
    • has(),has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中
    • delete(),delete方法删除某个键,返回true。若是删除失败,返回false
    • clear(),clear方法清除全部成员,没有返回值
  • 遍历方法(遍历顺序是插入顺序谁先插入谁先遍历到)
    • keys():返回键名的遍历器。
    • values():返回键值的遍历器。
    • entries():返回全部成员的遍历器。
    • forEach():遍历 Map 的全部成员
    • 将map数据转换成数组,最快的就是扩展运算符
    let mapData = new Map([
     ['name', 'zhan'],
     ['age', 25],
     ['sex', 'boy']
     ]);
     let ary = [...mapData.keys()]; // ['name','age','sex'];
     let ary_ =[...mapData.entries()]; // [['name', 'zhan'],['age', 25],['sex', 'boy']]
     let ary__ =[...mapData]; // [['name', 'zhan'],['age', 25],['sex', 'boy']]
    • Map数据没有map和filter方法,不过借助数组,能够间接实现
    const map0 = new Map()
      .set(1, 'a')
      .set(2, 'b')
      .set(3, 'c');
    
    const map1 = new Map(
      [...map0].filter(([k, v]) => k < 3)
    );

weakMap

  • 特性
    • 相似于Map结构,不一样的有如下几点
      • 只用对象做为键
      • WeakMap的键名所指向的对象,不计入垃圾回收机制
      • 没有遍历操做
  • 方法和属性
    • get()
    • set()
    • has()
    • delete()
    • 没有size属性,由于没有办法列出全部键名,某个键名是否存在彻底不可预测,跟垃圾回收机制是否运行相关, 为了防止出现不肯定性,就统一规定不能取到键名。二是没法清空,即不支持clear方法
  • 应用
    • WeakMap 应用的典型场合就是 DOM 节点做为键名,将dom做为键
    • 因为WeakMap的键名所指向的对象,不计入垃圾回收机制,一旦这个 DOM 节点删除,该状态就会自动消失,不存在内存泄漏风险。
    let myElement = document.getElementById('logo');
    let myWeakmap = new WeakMap();
    
    myWeakmap.set(myElement, {timesClicked: 0});
    
    myElement.addEventListener('click', function() {
      let logoData = myWeakmap.get(myElement);
      logoData.timesClicked++;
    }, false);
相关文章
相关标签/搜索