美文网首页
ES6 Set、Map

ES6 Set、Map

作者: 可爱的木头 | 来源:发表于2019-01-23 16:04 被阅读0次

    Set

    ES6提供了新的数据结构Set。它类似于数组。但是成的值都是唯一的,没有重复的值。
    Set本身是一个构造函数,用来生成Set数据结构。
    可以用来数组的去重。
    向Set加入值的时候,不会发生类型的转换,所以5和‘5’是两个不同的值。Set内部 判断两个值是否不同使用的算法类似于精确相等运算符(===),于‘===’的主要的区别的NaN等于自身 而‘===’ NaN是不等于自身的。
    对象基于指针问题 是不会相等的。

    const s = new Set();
    [2,3,4,5,6,4,3,4,2,2].forEach(x => s.add(x));
    for(let i of s){
      console.log(i);
    }
    //2,3,4,5,6
    const set = new Set([1,2,3,4,4])
    [...set]
    //1,2,3,4
    
    let set = new Set();
    let a = NaN;
    let b = NaN;
    set.add(a);
    set.add(b);
    set //Set{NaN};
    

    Set实例的属性和方法
    Set.prototype.constructor //指向本身
    Set.prototype.size //Set实例的成员总数

    方法:

    add() //增加
    delete() //删除
    has() //查询 返回Boolean
    clear() //清除所有

    遍历方法:

    keys()//返回键名
    values()//返回键值
    entries()//返回键值对数组
    forEach() //loop
    由于Set结构没有键名,只有键值所以keys和values方法的行为完全一致。

    let set = new Set(['red', 'green', 'blue']);
    for(let item of set.keys()){
      console.log(item);
    // red
    // green
    // blue
    }
    for(let item of set.values()){
      console.log(item);
    // red
    // green
    // blue
    }
    for(let item of set.entries()){
      console.log(item);
    // ["red", "red"]
    // ["green", "green"]
    // ["blue", "blue"]
    }
    //所以set的value获取直接可以用for...of获取
    for(let item of set){
      console.log(item);
    // red
    // green
    // blue
    }
    //Set结构的实例于数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值
    set.forEach((key,value) => {console.log(key + ' : ' + value)});
    // red:red
    // green:green
    // blue:blue
    
    运用扩展运算符
    let set = new Set(['red', 'green', 'blue']);
    [...set]
    //['red','green','blue']
    //扩展运算符与Set结构相结合,就可以去除数组的重复成员
    let set = [1,2,3,3,3,3,4,4,5];
    [...new Set(set)]
    //[1,2,3,4,5]
    new Set([...set].filter(x => {return x % 2 === 0}));
    //{2,4}
    
    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}
    
    改变Set值
    let set = new Set([1,2,3]);
    set = new Set([...set].map(x => x*2));
    //Set{2,4,6}
    set = new Set(Array.from(set,x => x * 2));
    //Set{2,4,6}
    

    WeakSet

    WeakSet结构与Set相似,也是不重复的值的集合。但是它与Set有两个区别。
    首先WeakSet的成员只能是对象,而不能是其他类型的值。其中的对象都是弱引用,随时可能小时,跟浏览器垃圾回收机制有关。不会出现内存泄漏。
    比较适合临时存放一组对象,以及存放跟对象绑定的信息。
    方法:add() delete() has()
    WeakSet不可遍历所以也没有size属性

    const ws = new WeakSet();
    ws.add(1)
    //TypeError:Invalid value used in weak set
    ws.add(Symbol());
    //TypeError:Invalid value used in weak set
    

    具有Iterable接口的对象,都可以作为WeakSet的参数。
    b数组的成员为WeakSet的成员,而不是b数组本身。这意味着,数组的成员只能是对象。

    const a = [[1,2],[3,4]];
    const ws = new WeakSet(a);
    //WeakSet{[1,2],[3,4]}
    const b = [1,2];
    const ws = new WeakSet(b);
    //uncaught TypeError:Invalid value used in weak set;
    

    Map

    Javascript的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。
    Map数据结构类似于对象,也是键值对的集合,但是与对象的区别是的繁为不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说Object结构提供了‘字符串-值’的对象,Map结构提供了‘值-值’的对象。这是一种更完善的Hash结构实现。如果你需要‘键值对’的数据结构,Map比Object更合适。

    属性:size 返回Map结构的成员总数
    方法:set get has delete clear
    //Map结构数据的增删改查。
    const m = new Map();
    const o = {p:'hello world'};
    m.set(o,'content');
    m.get(o)//content
    m.has(o)//true
    m.delete(o)//true
    m.has(o)//false
    m.clear();
    m.size //0
    
    遍历的方法 keys values entries forEach
    //Map数据结构可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。
    const map = new Map([
      ['name', '张三'],
      ['title', 'Author']
    ]);
    map.size //2
    map.has('name')//true
    map.get('name')//'张三'
    map.has('title')//true
    map.get('title')//'Author'
    
    //上面的例子解析执行的方法
    const items = [
      ['name', '张三'],
      ['title', 'Author']
    ]
    
    const map = new Map()
    items.forEach(([key,value]) => map.set(key,value))
    
    Set和Map都可以用来生成新的Map
    const set = new Set([
      ['foo',1],
      ['bar',2]
    ]);
    const m1 = new Map(set);
    m1.get('foo')//1
    const m2 = new Map([['bar',3]]);
    const m3 = new Map(m2);
    m3.get('bar')//3
    m3.set('bar',4)
    m3.get('bar')//4    如果对同一个键多次赋值,后面的值将覆盖前面的值
    
    new Map().get('sdfsdf')//undefined
    
    //如果键为对象要确定为同一个对象的引用
    const map = new Map()
    map.set(['a'],555);
    map.get(['a']);//undefined
    
    //同理,同样的值的两个实例,在Map结构中被视为两个键
    const map = new Map()
    var a = ['a'];
    var b = ['a']
    map.set(a,555);
    map.set(b,666)
    map.get(a);//555
    map.get(b);//666
    

    Map通过严格相等来判断是否为一个键。

    0 === -0//true
    true === 'true' //false
    undefined === null //false
    NaN === NaN //false   虽然NaN不严格相等于自身,但Map将其视为同一个键
    

    Map与其他数据结构的互相转换

    Map转为数组
    const map = new Map([
      ['F', 'no'],
      ['T',  'yes'],
    ]);
    [...map]
    
    数组转为Map
    new Map([...map])
    
    Map转为对象
    function Maptoobj(v){
      var obj = Object.create(null);
      for(let [key,value] of v){
        obj[key] = value
      }
      return obj
    }
    Maptoobj(map);
    
    对象转化为Map
    function objtomap(v){
      var map = new Map();
      for(let i of Object.keys(v)){
        map.set(i,v[i])
      }
      return map
    }
    objtomap({'a':1})
    
    Map 转化为Json 如果Map的键名都是字符串
    function maptojson(v){
      return JSON.stringify(Maptoobj(v))
    }
    let myMap = new Map().set('yes', true).set('no', false);
    maptojson(myMap)
    // '{"yes":true,"no":false}'
    
    如果Map的键名有非字符串
    function mapToArrayJson(map) {
      return JSON.stringify([...map]);
    }
    
    let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
    mapToArrayJson(myMap)
    // '[[true,7],[{"foo":3},["abc"]]]'
    
    JSON转化为Map
    function jsonToStrMap(jsonStr) {
      return objtomap(JSON.parse(jsonStr));
    }
    
    jsonToStrMap('{"yes": true, "no": false}')
    // Map {'yes' => true, 'no' => false}
    
    如果整个json是一个数组且每个数组成员本身又是一个又两个成员的数组
    function jsonToMap(jsonStr) {
      return new Map(JSON.parse(jsonStr));
    }
    
    jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
    // Map {true => 7, Object {foo: 3} => ['abc']}
    

    WeakMap

    与Map数据结构类似,也是用于生成键值对的集合 与Weakset一样突出弱引用的作用。
    与Map的区别
    1.和WeakSet一样只接受对象作为键名(null除外,null为对象 但是null不可以作为键名),不接受其他类型的值作为键名。

    const map = new WeakMap();
    map.set(1,2)
    //TypeError :1 is not an Object!
    map.set(Symbol(),2)
    //TypeError:Invalid value used as weak map key
    map.set(null,2)
    //TypeError:invalid value used as weak map key
    

    与WeakSet一样 WeakMap没有遍历操作(即没有keys() values() entries()方法)也没有size属性。也不支持clear()方法。

    const wm = new WeakMap()
    wm.size //undefined
    wm.clear//undefined
    wm.forEach//undefined
    

    相关文章

      网友评论

          本文标题:ES6 Set、Map

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