JavaScript WeakMap使用详解


Posted in Javascript onFebruary 05, 2021

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

语法

new WeakMap([iterable])

参数

iterable
Iterable 是一个数组(二元数组)或者其他可迭代的且其元素是键值对的对象。每个键值对会被加到新的 WeakMap 里。null 会被当做 undefined。

描述

WeakMap 的 key 只能是 Object 类型。 原始数据类型 是不能作为 key 的(比如 Symbol)。

Why WeakMap?

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

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

相比之下,原生的 WeakMap 持有的是每个键对象的“弱引用”,这意味着在没有其他引用存在时垃圾回收能正确进行。原生 WeakMap 的结构是特殊且有效的,其用于映射的 key 只有在其没有被回收时才是有效的。

正由于这样的弱引用,WeakMap 的 key 是不可枚举的 (没有方法能给出所有的 key)。如果key 是可枚举的话,其列表将会受垃圾回收机制的影响,从而得到不确定的结果。因此,如果你想要这种类型对象的 key 值的列表,你应该使用 Map。

基本上,如果你要往对象上添加数据,又不想干扰垃圾回收机制,就可以使用 WeakMap。

属性

  • WeakMap.length

length  属性的值为 0。

  • WeakMap.prototype

WeakMap 构造器的原型。 允许添加属性到所有的 WeakMap 对象。

WeakMap 实例

所有 WeakMap 实例继承自 WeakMap.prototype.

属性

WeakMap.prototype.constructor
返回创建WeakMap实例的原型函数。 WeakMap函数是默认的。

方法

  • WeakMap.prototype.delete(key)

移除key的关联对象。执行后 WeakMap.prototype.has(key)返回false。

  • WeakMap.prototype.get(key)

返回key关联对象, 或者 undefined(没有key关联对象时)。

  • WeakMap.prototype.has(key)

根据是否有key关联对象返回一个Boolean值。

  • WeakMap.prototype.set(key, value)

在WeakMap中设置一组key关联对象,返回这个 WeakMap对象。

示例

使用 WeakMap

const wm1 = new WeakMap(),
   wm2 = new WeakMap(),
   wm3 = new WeakMap();
const o1 = {},
   o2 = function(){},
   o3 = window;

wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // value可以是任意值,包括一个对象或一个函数
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // 键和值可以是任意对象,甚至另外一个WeakMap对象

wm1.get(o2); // "azerty"
wm2.get(o2); // undefined,wm2中没有o2这个键
wm2.get(o3); // undefined,值就是undefined

wm1.has(o2); // true
wm2.has(o2); // false
wm2.has(o3); // true (即使值是undefined)

wm3.set(o1, 37);
wm3.get(o1); // 37

wm1.has(o1);  // true
wm1.delete(o1);
wm1.has(o1);  // false

实现一 个带有 .clear() 方法的类 WeakMap 类

class ClearableWeakMap {
 constructor(init) {
  this._wm = new WeakMap(init)
 }
 clear() {
  this._wm = new WeakMap()
 }
 delete(k) {
  return this._wm.delete(k)
 }
 get(k) {
  return this._wm.get(k)
 }
 has(k) {
  return this._wm.has(k)
 }
 set(k, v) {
  this._wm.set(k, v)
  return this
 }
}

规范

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262) WeakMap Standard Initial definition.
ECMAScript (ECMA-262) WeakMap Living Standard

以上就是JavaScript WeakMap使用详解的详细内容,更多关于JavaScript WeakMap的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
让js弹出窗口居前显示的实现方法
Jul 10 Javascript
IE与FireFox的JavaScript兼容问题解决办法
Dec 31 Javascript
jQuery自带的一些常用方法总结
Sep 03 Javascript
jquery实现上下左右滑动的方法
Feb 09 Javascript
详谈LABJS按需动态加载js文件
May 07 Javascript
jquery实现动静态条形统计图
Aug 17 Javascript
微信小程序 wxapp视图容器 view详解
Oct 31 Javascript
jQuery Validate设置onkeyup验证的实例代码
Dec 09 Javascript
再谈Angular4 脏值检测(性能优化)
Apr 23 Javascript
对angular 实时更新模板视图的方法$apply详解
Oct 09 Javascript
Layui实现数据表格默认全部显示(不要分页)
Oct 26 Javascript
openlayers4实现点动态扩散
Aug 17 Javascript
JavaScript 声明私有变量的两种方式
Feb 05 #Javascript
node.js文件的复制、创建文件夹等相关操作
Feb 05 #Javascript
Vant+postcss-pxtorem 实现浏览器适配功能
Feb 05 #Javascript
JavaScript代码实现微博批量取消关注功能
Feb 05 #Javascript
js属性对象的hasOwnProperty方法的使用
Feb 05 #Javascript
关于element的表单组件整理笔记
Feb 05 #Javascript
详解JavaScript中的this指向问题
Feb 05 #Javascript
You might like
第四节 构造函数和析构函数 [4]
2006/10/09 PHP
php while循环控制的简单实例
2016/05/30 PHP
在jQuery 1.5中使用deferred对象的代码(翻译)
2011/03/10 Javascript
TreeView 用法(有代码)(asp.net)
2011/07/15 Javascript
使用insertAfter()方法在现有元素后添加一个新元素
2014/05/28 Javascript
javaScript中push函数用法实例分析
2015/06/08 Javascript
jquery.fastLiveFilter.js实现输入自动过滤的方法
2015/08/11 Javascript
AngularJS ngModel实现指令与输入直接的数据通信
2016/09/21 Javascript
JS常用加密编码与算法实例总结
2016/12/22 Javascript
vue-cli3 karma单元测试的实现
2019/01/18 Javascript
vue列表单项展开收缩功能之this.$refs的详解
2019/05/05 Javascript
微信小程序webview与h5通过postMessage实现实时通讯的实现
2019/08/20 Javascript
原生JavaScript创建不可变对象的方法简单示例
2020/05/07 Javascript
Vue项目配置跨域访问和代理proxy设置方式
2020/09/08 Javascript
[20:57]Ti4主赛事第三天开幕式
2014/07/21 DOTA
Python bsddb模块操作Berkeley DB数据库介绍
2015/04/08 Python
python使用smtplib模块通过gmail实现邮件发送的方法
2015/05/08 Python
利用 Monkey 命令操作屏幕快速滑动
2016/12/07 Python
python3 pillow生成简单验证码图片的示例
2017/09/19 Python
一篇文章彻底搞懂Python中可迭代(Iterable)、迭代器(Iterator)与生成器(Generator)的概念
2019/05/13 Python
Python常用模块logging——日志输出功能(示例代码)
2019/11/20 Python
英国最全面的橄榄球联盟门票网站:Live Rugby Tickets
2018/10/06 全球购物
如何在Cookie里面保存Unicode和国际化字符
2013/05/25 面试题
工作岗位说明书模板
2014/05/09 职场文书
幼儿园师德师风学习材料
2014/05/29 职场文书
环境工程专业自荐信范文
2014/06/24 职场文书
科学发展观活动总结
2014/08/28 职场文书
群众路线教育查摆剖析材料
2014/10/10 职场文书
法定代表人授权委托书格式
2014/10/14 职场文书
初中信息技术教学计划
2015/01/22 职场文书
邓小平文选读书笔记
2015/06/29 职场文书
迎新年主持词
2015/07/06 职场文书
Python3 使用pip安装git并获取Yahoo金融数据的操作
2021/04/08 Python
Win10鼠标轨迹怎么开 Win10显示鼠标轨迹方法
2022/04/06 数码科技
vue整合百度地图显示指定地点信息
2022/04/06 Vue.js
golang的文件创建及读写操作
2022/04/14 Golang