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 相关文章推荐
jquery蒙版控件实现代码
Dec 08 Javascript
js简易namespace管理器 实例代码
Jun 21 Javascript
js密码强度实时检测代码
Mar 02 Javascript
AngularJS基础 ng-options 指令详解
Aug 02 Javascript
Jquery删除css属性的简单方法
Dec 04 Javascript
jQuery展示表格点击变色、全选、删除
Jan 05 Javascript
canvas实现粒子时钟效果
Feb 06 Javascript
JS字符串统计操作示例【遍历,截取,输出,计算】
Mar 27 Javascript
详解webpack+express多页站点开发
Dec 22 Javascript
BootStrap自定义popover,点击区域隐藏功能的实现
Jan 23 Javascript
了解JavaScript中的选择器
May 24 Javascript
JavaScript canvas绘制折线图
Feb 18 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
学习php设计模式 php实现原型模式(prototype)
2015/12/07 PHP
Thinkphp实现短信验证注册功能
2016/10/18 PHP
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
JavaScript基本编码模式小结
2012/05/23 Javascript
Json字符串转换为JS对象的高效方法实例
2013/05/01 Javascript
jQuery 插件开发指南
2014/11/14 Javascript
jquery+CSS实现的水平布局多级网页菜单效果
2015/08/24 Javascript
探讨:JavaScript ECAMScript5 新特性之get/set访问器
2016/05/05 Javascript
javascript self对象使用详解
2016/10/18 Javascript
Javascript刷新页面的实例
2017/09/23 Javascript
JavaScript使用面向对象实现的拖拽功能详解
2019/06/12 Javascript
layui操作列按钮个数和文字颜色的判断实例
2019/09/11 Javascript
Vue快速实现通用表单验证的方法
2020/02/24 Javascript
Vue左滑组件slider使用详解
2020/08/21 Javascript
javascript实现前端分页功能
2020/11/26 Javascript
[01:10]DOTA2次级职业联赛 - Fly战队宣传片
2014/12/01 DOTA
[55:25]VGJ.T vs Optic Supermajor小组赛D组 BO3 第三场 6.3
2018/06/04 DOTA
Python的Django框架中使用SQLAlchemy操作数据库的教程
2016/06/02 Python
定制FileField中的上传文件名称实例
2017/08/23 Python
Python中列表list以及list与数组array的相互转换实现方法
2017/09/22 Python
Python  unittest单元测试框架的使用
2018/09/08 Python
Python 给某个文件名添加时间戳的方法
2018/10/16 Python
用Python写一个模拟qq聊天小程序的代码实例
2019/03/06 Python
Python2和Python3中@abstractmethod使用方法
2020/02/04 Python
python函数调用,循环,列表复制实例
2020/05/03 Python
Python 如何在字符串中插入变量
2020/08/01 Python
CSS3,线性渐变(linear-gradient)的使用总结
2017/01/09 HTML / CSS
英格兰足协官方商店:England Store
2019/07/12 全球购物
新学期班主任寄语
2014/01/18 职场文书
单位未婚证明范本
2014/01/18 职场文书
幼儿教师培训感言
2014/03/08 职场文书
民主生活会主持词
2015/07/01 职场文书
2016大学迎新晚会开场白
2015/11/24 职场文书
PO模式在selenium自动化测试框架的优势
2022/03/20 Python
Ruby处理YAML和json数据
2022/04/18 Ruby
Golang ort 中的sortInts 方法
2022/04/24 Golang