美文网首页
set、WeakSet、 map、 WeakMap区别

set、WeakSet、 map、 WeakMap区别

作者: 仔崽06 | 来源:发表于2020-11-24 15:33 被阅读0次

    1.es6新增Set结构,类似数组,但是成员值都是唯一的不能重复.Set本身是一个构造函数.需要new.

     let set =new Set([1,2,2,3,21,3,4]);
     console.log(set)  //Set({0: 1,1: 2,2: 3,3: 21,4: 4})
    //将set数据结构转换为数组
    let arr=Array.from(set) //[1, 2, 3, 21, 4]
    //或
    let arr=[...set];  //[1, 2, 3, 21, 4]
    

    set对象存储值是唯一的,所有需要判断两个值是否恒等.有几个特殊值需要特殊对待:

    • +0与-0在存储判断唯一性的时候是恒等的,所以不重复.
    • undefined与undefined是恒等的,所以不重复.
    • NaN与NaN不是恒等的,但是Set中只能保存一个,不重复.
     let set=new Set([0,-0]);
     console.log(set)  //Set(1){0}
     let set=new Set([undefined,undefined]);
     console.log(set)  //Set(1) {undefined}
     let set=new Set([NaN,NaN]);
     console.log(set) //Set(1) {NaN}
    

    set遍历的几种方式

    set.forEach(item=>{
         console.log(item)  //1, 2, 3, 21, 4
    })
    for(let i of set){
         console.log(i) //1, 2, 3, 21, 4
    }
    for(let i of set.keys()){
         console.log(i) //1, 2, 3, 21, 4
    }
    for(let i of set.values()){
         console.log(i) //1, 2, 3, 21, 4
    }
    for(let i of set.entries()){
         console.log(i)  //[1,1] [2, 2] [3, 3] [21, 21] [4, 4]
    }
    

    Set实例的属性和方法

    //add添加
    let set=new Set()
    set.add(1) //Set(1) {1}
    
    //delete删除
    let set=new Set();
    set.add(1);
    set.add(2);
    set.delete(1)
    console.log(set) //Set(1) {2}
    
    //判断是否包含
    let set=new Set([1,2,3]);
    let has=set.has(1)
    console.log(has)  //true
    
    //size元素个数
    let set=new Set([1,2,3]);
    console.log(set.size)  //3
    
    //clear清空数组成员没有返回值
    let set=new Set([1,2,3]);
    set.clear()
    console.log(set.size)  //0
    

    Set的基本使用

     //1.数组去重
    let arr=[1,2,3,4,5,2,1,4]
    let set=[...new Set(arr)];
    console.log(set) //[1, 2, 3, 4, 5]
    
    //2.并集
    let arr1=[1,2,3]
    let arr2=[2,3,4]
    let set=Array.from(new Set([...arr1,...arr2]));
    console.log(set) //[1, 2, 3, 4]
    
    //3.交集
    let arr1=new Set([1,2,3])
    let arr2=new Set([2,3,4])
    let set=[...arr1].filter(item=>arr2.has(item))
    console.log(set) //[2,3]
    
    //4.差集
    let arr1=new Set([1,2,3])
    let arr2=new Set([2,3,4])
    let set=[...arr1].filter(item=>!arr2.has(item))
    console.log(set) //[1]
    

    2.WeackSet与Set类似,也是不重复的值的集合,区别在于成员只能是引用类型,而不能是其他类型的值。

    let ws=new WeakSet();
    ws.add(1);
    console.log(ws) //error
    
    let weakSet=new WeakSet([2,3]);
    console.log(weakSet) //error
    
    let arr=[1,2]
    let arr1=[1,2]
    let ws=new WeakSet([arr,arr1]); 
    console.log(ws) //WeakSet {Array(2), Array(2)}
    
    let obj={name:1}
    let obj2={name:1}
    let ws=new WeakSet([obj,obj2]); 
    console.log(ws) //WeakSet {{…}, {…}}
    

    WeakSet中的对象都是弱引用,即垃圾回收机制就不会考虑WeakSet对该对象的应用,如果其他对象都不不在引用该对象,那么垃圾回收机制就会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet中.所以WeakSet没有size,不能遍历.

    let obj={name:'zdb'}
    let ws=new WeakSet([obj]);//WeakSet {{…}}// [[Entries]]// 0:// value: {name: "zdb"}// __proto__: WeakSet
    console.log(ws)
    obj=null
    setTimeout(()=>{
      console.log(ws.has(obj)) //false
    },5000)
    
    

    WeakSet实例的属性和方法

    //add添加
    let arr=[1,2]
    let ws=new WeakSet();
    ws.add(arr);
    console.log(ws) //WeakSet {Array(2)}
    
    //has是否包含
    let obj={name:'zdb'}
    let ws=new WeakSet([obj]);
    console.log(ws.has(obj)) //true
    
    //delete删除
    let obj={name:'zdb'}
    let ws=new WeakSet([obj]);
    ws.delete(obj)
    console.log(ws) //WeakSet {}
    
    

    WeakSet使用场景

    //深copy
    let obj={name:1,age:new RegExp(/\d/),fn:function(){console.log(1)},sex:null,school:undefined};
    let copy_obj=JSON.parse(JSON.stringify(obj)); //正则转换为对象 function undefined 直接忽略 
    
    let obj={name:1,age:/\d/,fn:function(){console.log(1)},date:new Date,sex:null,school:undefined}; 
    obj.o=obj
    let deepClone=(target,weak=new WeakSet())=>{
          if(typeof target !=='object' || target===null) return target
          if(target instanceof RegExp) return new RegExp(target)
          if(target instanceof Date) return new Date(target)
          //如果是对象,数组
          let o=new target.constructor();
          if(!weak.has(target)){
             weak.add(target)
          }else{
             return target
          }
          for(let key in target){
             o[key]= typeof target[key]==='object' ? deepClone(target[key],weak):target[key]
          }
            return o
      }
     console.log(deepClone(obj)) //{age: /\d/,date: Tue Nov 24 2020 11:40:18 GMT+0800(中国标准时间) {},fn: ƒ (),name: 1,o: {name: 1, age: /\d/, date: Tue Nov 24 2020 11:40:18 GMT+0800 (中国标准时间), sex: null, fn: ƒ, …},school: undefined,sex: null}
    

    Map Javascript的对象,本质上是键值对的集合,但是传统意义上只能用字符串当做键,这个给他的使用带来很大的限制. es6提供了Map数据结构,也是键值对集合,键的范围不限于字符串.

     let obj={name:1};
     let obj1={
         [obj]:1
     }
     console.log(obj1['[object Object]']) //1
     console.log(obj1[Object.prototype.toString()]) //1
    
     const m=new Map()
     let o={p:'hello'}
     m.set(2,3)
     m.set(o,123)
     console.log(m) //Map(2) {2 => 3, {…} => 123}
    
     const map=new Map([[2,4],['dw',2]])
     console.log(map) //Map(2) {2 => 4, "dw" => 2}
    

    map实例的属性和方法

    //size成员个数
    const m=new Map([[1,2]])
    console.log(m.size) //1
    
     //set添加
    const m=new Map([[1,2]])
    m.set(3,10)  //key,value
    console.log(m) //Map(2) {1 => 2, 3 => 10}
    
    //get获取
    const m=new Map([[1,3]])
    console.log(m.get(1)) //3
    
     //delete删除
    const m=new Map([[1,3]])
    m.delete(1)
    console.log(m) //Map(0) {}
    
    //has是否包含
    const m=new Map([[1,3]])
    console.log(m.has(1)) //true
    
    //clear清空
    const m=new Map([[1,3]])
    m.clear()
    console.log(m.size) //0
    

    map遍历的方法

     const m=new Map([[1,3],['34',45]])
     m.forEach(item=>{
          console.log(item)  //3 45
     })
     for(let key of m.keys()){
          console.log(key)  //1 34
     }
     for(let val of m.values()){
          console.log(val)  //3 45
     }
     for(let ent of m.entries()){
          console.log(ent) //[1, 3] ["34", 45]
     }
    

    map快速转换为数组结构

    const map = new Map([
           [1, 'one'],
           [2, 'two'],
           [3, 'three'],
    ]);
    console.log([...map.keys()]) //[1, 2, 3]
    console.log([...map.entries()]) //[[1, 'one'], [2, 'two'],[3, 'three']]
    console.log([...map.values()])//["one", "two", "three"]
    

    WeakMap与Map类似,与Map的区别是。WeakMap只接受对象为键名null除外,其次WeakMap是弱引用,不计入垃圾回收机制.

    const map=new WeakMap();
    map.set(1,2)  //error
    map.set(null,2) //error
    
    //weakMap弱引用只是键名不是键值
    const wm=new WeakMap();
    let key={}
    let obj={foo:1}
    wm.set(key,obj)
    obj=null
    console.log(wm.get(key)) //{foo: 1}
    
    const wm=new WeakMap();
    let key={}
    let obj={foo:1}
    wm.set(key,obj)
    key=null
    console.log(wm.get(key)) //undefined
    

    WeakMap包含的4种方法

    //set设置
    const wm=new WeakMap();
    wm.set({},2) //key,value
    console.log(wm) //WeakMap {{…} => 2}
    
    //get获取
    const wm=new WeakMap();
    let key={}
    wm.set(key,2) //key,value
    console.log(wm.get(key)) //2
    
    //has是否包含
    const wm=new WeakMap();
    let key={}
    wm.set(key,2) //key,value
    console.log(wm.has(key)) //true
    
    //delete删除
    const wm=new WeakMap();
    let key={}
    wm.set(key,2) 
    wm.delete(key)
    console.log(wm.has(key)) //false
    
    

    相关文章

      网友评论

          本文标题:set、WeakSet、 map、 WeakMap区别

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