JavaScript WeakMap的具体使用

 更新时间:2023年02月17日 09:29:02   作者:白瑕  
本文主要介绍了JavaScript WeakMap的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

我在处理一个复杂对象的深拷贝方法时接触到WeakMap, 其作为缓存结构以解决对象内部的循环引用问题. 为了改造这个方法, 决定研究WeakMap.

一、为何选用WeakMap

WeakMap和Map都可以使用对象作为键, Map也可以使用基本数据类型作为键, 在特殊的情况下(都使用对象作为键), 两者看起来并无差别.

1. Map

Map会阻止JavaScript的内存回收机制对 以一个已经被回收的对象作为键的元素 进行回收.
与Map内存储元素的方式有关:

A map API could be implemented in JavaScript with two arrays (one for keys, one for values) shared by the four API methods.
`map`在JavaScript内可通过使两个数组被4种方法共享来实现, 向`Map`内设置元素时分别将键和值`push`进这两个数组.
Setting elements on this map would involve pushing a key and value onto the end of each of those arrays simultaneously.
访问`Map`取值时需要遍历, 从两个数组内找到匹配的值.

var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
sayings.set('elephant', 'toot');
sayings.size; // 3
sayings.get('fox'); // undefined
sayings.has('bird'); // false
sayings.delete('dog');
sayings.has('dog'); // false

for (var [key, value] of sayings) {
  console.log(key + ' goes ' + value);
}
// "cat goes meow"
// "elephant goes toot"

sayings.clear();
sayings.size; // 0

首先Map内部基于数组实现, 取值赋值需要遍历, 时间复杂度上来了:

The first one is an O(n) set and search (n being the number of keys in the map)
首先设置和查找的时间复杂度都是O(n), n是Map内键的数量.
since both operations must iterate through the list of keys to find a matching value.
因为两个操作都必须遍历每一个键以找到匹配的值.

其次数组会一直保留着对元素的引用, 这跟元素是否为引用类型无关, 只要数组不被销毁, 元素的引用也不会被销毁:

let ele1 = 'ele1';
let ele2 = { key: 'value' };

let arr = [ ele1, ele2 ];

ele1 = null; // 设置为null脱离当前执行环境, 以便回收机制回收
ele2.key = null;

console.log(arr);
// [ 'ele1', { key: 'null' } ]

前面提到Map内部可以通过两个数组实现, 那么意味着在Map需要销毁前, Map内的键和值都无法被JavaScript垃圾回收机制回收, Map可能会变得臃肿庞大导致内存不足(内存泄漏).

持有原始对象引用的映射实际上意味着对象不能被垃圾回收, 这可能会导致意外的内存问题.
如果你希望存储在映射中的对象具有与原始对象相同的生命周期, 请考虑使用 WeakMap.

2. WeakMap

WeakMap同Map是键值对的集合, 但它的键被弱保持, 即当键所指的对象未在其他地方被引用时, 将被垃圾回收机制回收.
其键必须是对象, 值可以是任意数据类型.

也由于这种弱引用实现的垃圾回收可执行, WeakMap内元素的存在变得不可预知(可能垃圾回收机制目前没有回收至此处, 但此处应当回收.), 为了防止执行时出现意外, WeakMap没有提供枚举方法.

正由于这样的弱引用, WeakMap的key是不可枚举的(没有方法能给出所有的 key).
如果key可枚举, 其列表将受垃圾回收机制的影响, 从而得到不确定的结果。

但是WeakMap提供的接口与Map相同, 可以通过接口稳定的访问元素.

let ele1 = { key: "value" };

let weak = new WeakMap();
weak.set(ele1, "ele1");

ele1 = null;

console.log(weak); // WeakMap { <items unknown> } 不赋值null此处结果相同
console.log(weak.get(ele1)); // undefined 销毁 不赋值null此处为'ele1'

总之, 相比Map, 它更干净利落, 更节约内存.
但是你如果有枚举需求, 或者就是需要一直保存着key不回收, 那就用Map.

二、WeakMap原型方法

指明需要何种操作, 并指明需要操作的键值对的key, 直接传变量即可.

方法描述
WeakMap.prototype.delete(key)删除WeakMap中与key相匹配的value.
WeakMap.prototype.get(key)返回WeakMap中与key相关联的值, 如果key不存在则返回undefined.
WeakMap.prototype.has(key)返回布尔值, 断言WeakMap对象中该key是否存在.
WeakMap.prototype.set(key, value)WeakMap中设置一组新的键值对, 返回设置完毕后的WeakMap对象.

总结

到此这篇关于JavaScript WeakMap的具体使用的文章就介绍到这了,更多相关JavaScript WeakMap内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • p5.js临摹动态图形的方法

    p5.js临摹动态图形的方法

    这篇文章主要为大家详细介绍了p5.js临摹动态图形的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • webpack之devtool详解

    webpack之devtool详解

    这篇文章主要介绍了webpack之devtool详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • js菜单代码js菜单特效代码

    js菜单代码js菜单特效代码

    不用div+css实现的js菜单特效代码用js+table实现 默认选中一个,点击后 选中的项目“变白”。不用css+div 高手给做一下 多谢了 演示站:www.allss.com.cn 演示站使用css+div的 改成js+table的
    2008-01-01
  • Uniapp全局消息提示以及其组件的实现方法

    Uniapp全局消息提示以及其组件的实现方法

    当时在做登录那边需要做一些交互,所以必不可少要用到消息提示框,下面这篇文章主要给大家介绍了关于Uniapp全局消息提示以及其组件的实现方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • BootStrap初学者对弹出框和进度条的使用感觉

    BootStrap初学者对弹出框和进度条的使用感觉

    这篇文章主要介绍了BootStrap初学者对弹出框和进度条的使用感觉的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • JavaScript实现单击网页任意位置打开新窗口与关闭窗口的方法

    JavaScript实现单击网页任意位置打开新窗口与关闭窗口的方法

    这篇文章主要介绍了JavaScript实现单击网页任意位置打开新窗口与关闭窗口的方法,涉及javascript窗口的相关操作函数与使用技巧,需要的朋友可以参考下
    2017-09-09
  • JS来动态的修改url实现对url的增删查改

    JS来动态的修改url实现对url的增删查改

    通过get方式提交post表单等方式来动态修改url存在诸多的不妥,因此,想到了通过JS来动态的修改url,来实现对url的增删查改
    2014-09-09
  • js注册时输入合法性验证方法

    js注册时输入合法性验证方法

    这篇文章主要为大家详细介绍了js注册时输入合法性验证方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • JS启动应用程序的一个简单例子

    JS启动应用程序的一个简单例子

    用jscript实现启动程序一个例子
    2008-05-05
  • 轻松掌握JavaScript享元模式

    轻松掌握JavaScript享元模式

    这篇文章主要帮助大家轻松掌握JavaScript享元模式,告诉大家想什么是js享元模式,感兴趣的小伙伴们可以参考一下
    2016-08-08

最新评论