• Javascript学习-WeakMap


    一、含义

      WeakMap Map 一样,都是用于生成键值对的集合

    const key=['1',2];
    const myWeakMap=new WeakMap().set(key,'2');
    console.log(myWeakMap.get(key))  // 2

      他也可以接受一个数组来作为参数:

    const k1={key:'1'}
    const k2={key:"2"}
    const arr=[[k1,'1'],[k2,2]]
    const myWeakMap=new WeakMap(arr)
    console.log(myWeakMap.get(k1)) // 1

       

    WeakMap 和 Map 的区别:

      (1)WeakMap 只接受对象(null 除外)作为键名

      (2)WeakMap 里面的键对象是不会被记入垃圾回收机制的。

    注意:WeakMap 弱引用的只是键,而不是键值对,键值对还是正常引用的。

    二、WeakMap 的语法

      WeakMap Map 在Api 上的区别主要是有两个,一个是没有遍历操作(没有key(),values()和entries()方法),也没有size 属性,因为没有方法列出所有的键名,某个键名是否存在是不可以被知道的,和垃圾回收机制是否运行相关。二是无法清空,即它不支持clear 方法。因此,WeakMap只有四个方法可以使用:get(),set(),has(),delete();

    三、WeakMap 的用途

      (1)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)
      上面的代码中,myElement 是一个 DOM 节点,每当发生了 click 事件就会更新一下状态,我们将这个状态作为键值放在了WeakMap 里面,对应的键名就是myElement,一旦这个Dom节点删除,这个状态就会消失,不存在内存泄漏的问题。
      
      进一步来讲,可以将事件处理程序存放到 WeakMap 里面来,如下:
    const listener=new WeakMap()
    
    listener.set(element1,handler1)
    listener.set(element2,handler2)
    
    element1.addEventListener('click',listener.get(element1),false)
    element2.addEventListener('click',listener.get(element2),false)

       (2)WeakMap 的另一用途是缓存计算结果,如下:

    const cache=new WeakMap() // 创建一个弱引用
    function countKeys(obj){
      // 判断弱引用里面是否有obj
      if(cache.has(obj)){
        return [cache.get(obj),'cached']
      }else{
        const count=Object.keys(obj).length;
        cache.set(obj,count)
        return [count,'computed']
      }
    }
    
    let obj={name:'kakuqo',age:30};
    console.log(countKeys(obj)) // [ 2, 'computed' ]
    console.log(countKeys(obj)) // [ 2, 'cached' ]
    
    obj=null;

      (3)WeakMap 还可以用来部署私有属性,如下:

    const _counter=new WeakMap();
    const _action=new WeakMap();
    
    class Countdown{
      // 传递两个参数
      constructor(counter,action){
        _action.set(this,action);
        _counter.set(this,counter)
      }
      dec(){
        let counter=_counter.get(this);
        if(counter<1) return;
        counter--;
        _counter.set(this,counter);
        if(counter===0){
          _action.get(this)()
        }
      }
    }
    
    const c=new Countdown(2,()=>console.log('DONE'))
    c.dec()
    c.dec() // DONE

      由于传递的两个参数都是弱引用,如果删除这个实例,这两个参数也会随之消失,不会造成内存泄漏。

  • 相关阅读:
    高级定制_百度百科
    大叔也学Xamarin系列
    WebApi系列~dynamic让你的省了很多临时类
    大叔也说Xamarin~Android篇~支付宝SDK的集成
    知方可补不足~sqlserver中使用ROW_NUMBER进行的快速分页
    EF架构~有时使用SQL更方便
    【deep learning学习笔记】注释yusugomori的LR代码 --- LogisticRegression.h
    线程同步
    泛型接口的实现方式之二
    jsp获得本地及serverIP的方法
  • 原文地址:https://www.cnblogs.com/zhilili/p/14763590.html
Copyright © 2020-2023  润新知