WeakMap的用法和使用场景

WeakMap

弱引用
WeakMap 对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的,WeakMap 的 key 是不可枚举的。
Why WeakMap ?

在 JavaScript 里,map API 可以 通过使其四个 API 方法共用两个数组(一个存放键,一个存放值)来实现。给这种 map 设置值时会同时将键和值添加到这两个数组的末尾。从而使得键和值的索引在两个数组中相对应。当从该 map 取值的时候,需要遍历所有的键,然后使用索引从存储值的数组中检索出相应的值。

但这样的实现会有两个很大的缺点:

首先赋值和搜索操作都是 O(n) 的时间复杂度(n 是键值对的个数),因为这两个操作都需要遍历全部整个数组来进行匹配。
另外一个缺点是可能会导致内存泄漏,因为数组会一直引用着每个键和值。这种引用使得垃圾回收算法不能回收处理他们,即使没有其他任何引用存在了。

场景一(事件处理的绑定)

const btn1 = document.querySelector("#btn1");
const btn2 = document.querySelector("#btn2");

btn1.addEventListener("click", handleBtn1Click);
btn2.addEventListener("click", handleBtn2Click);

function handleBtn1Click() {}
function handleBtn2Click() {}

// 当不需要btn1 和 btn2 两个节点的失火,因为绑定了监听函数,所以不会被垃圾回收机制回收
btn1.remove();
btn2.remove();

// 必须置空才能被回收
handleBtn1Click = null
handleBtn2Click = null

使用WeakMap
WeakMap键名是弱引用,键名都被回收了,键值一并被回收,则不需要再对 handleBtn1Click handleBtn2Click 进行清空

const btn1 = document.querySelector("#btn1");
const btn2 = document.querySelector("#btn2");

const btnMap = new WeakMap()

// 弱引用 btn1 btn2 没被引用则自动回收
btnMap.set(btn1,handleBtn1Click)
btnMap.set(btn2,handleBtn2Click)

btn1.addEventListener("click", btnMap.get(btn1));
btn2.addEventListener("click", btnMap.get(btn2));

function handleBtn1Click() {}
function handleBtn2Click() {}

btn1.remove();
btn2.remove();

场景二 (解决深拷贝死循环问题)

let test1 = {};
let test2 = {};

test2.test1 = test;
test1.test2 = test2;

使用WeakMap来记录是否拷贝过

function deepClone(origin, hashMap = new WeakMap()) {
  if (typeof origin == undefined && typeof origin !== "object") {
    return origin;
  }

  if (origin instanceof Date) {
    return new Date(origin);
  }

  if (origin instanceof RegExp) {
    return new RegExp(origin);
  }

  const hashKey = hashMap.get(origin);
  if (hashKey) return hashKey;

  const target = new origin.constructor();
  hashMap.set(origin, target);

  for (const k in origin) {
    if (origin.hasOwnProperty(k)) {
      target[k] = deepClone(origin[k], hashMap);
    }
  }
  return target;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值