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 相关文章推荐
window.open以post方式将内容提交到新窗口
Dec 26 Javascript
js实现div闪烁原理及实现代码
Jun 24 Javascript
js实现的简洁网页滑动tab菜单效果代码
Aug 24 Javascript
深入理解JavaScript中的call、apply、bind方法的区别
May 30 Javascript
js实现四舍五入完全保留两位小数的方法
Aug 02 Javascript
jQuery实现的简单拖拽功能示例
Sep 13 Javascript
javascript高级模块化require.js的具体使用方法
Oct 31 Javascript
javaScript动态添加Li元素的实例
Feb 24 Javascript
详解vue-cli官方脚手架配置
Jul 20 Javascript
对vue中v-if的常见使用方法详解
Sep 28 Javascript
vue中keep-alive、activated的探讨和使用详解
Jul 26 Javascript
解决vue打包 npm run build-test突然不动了的问题
Nov 13 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
德劲1102收音机的打理维修案例
2021/03/02 无线电
深入理解require与require_once与include以及include_once的区别
2013/06/05 PHP
PHP5.3与5.5废弃与过期函数整理汇总
2014/07/10 PHP
thinkphp数据查询和遍历数组实例
2014/11/28 PHP
PHP MySql增删改查的简单实例
2016/06/21 PHP
ThinkPHP实现转换数据库查询结果数据到对应类型的方法
2017/11/16 PHP
Javascript注入技巧
2007/06/22 Javascript
改善用户体验的五款jQuery插件分享
2011/05/22 Javascript
鼠标经过显示二级菜单js特效
2013/08/13 Javascript
JS日期格式化之javascript Date format
2015/10/01 Javascript
基于JavaScript实现div层跟随滚动条滑动
2016/01/12 Javascript
详解JavaScript异步编程中jQuery的promise对象的作用
2016/05/03 Javascript
Angularjs 依赖压缩及自定义过滤器写法
2017/02/04 Javascript
JS实现的计数排序与基数排序算法示例
2017/12/04 Javascript
微信小程序实现文字跑马灯效果
2020/05/26 Javascript
Python yield使用方法示例
2013/12/04 Python
Python黑帽编程 3.4 跨越VLAN详解
2016/09/28 Python
tensorflow 使用flags定义命令行参数的方法
2018/04/23 Python
从DataFrame中提取出Series或DataFrame对象的方法
2018/11/10 Python
Python面向对象基础入门之编码细节与注意事项
2018/12/11 Python
python图片二值化提高识别率代码实例
2019/08/24 Python
Python Opencv图像处理基本操作代码详解
2020/08/31 Python
html5播放视频且动态截图实现步骤与代码(支持safari其他未测试)
2013/01/06 HTML / CSS
Keds官方网站:购买帆布运动鞋和经典皮鞋
2016/11/12 全球购物
迪卡侬印尼体育用品商店:Decathlon印尼
2020/03/11 全球购物
入党思想汇报
2014/01/05 职场文书
两只小狮子教学反思
2014/02/05 职场文书
医药类个人求职的自我评价
2014/02/12 职场文书
大学学习个人的自我评价
2014/02/18 职场文书
公务员平时考核实施方案
2014/03/11 职场文书
升旗仪式主持词
2014/03/19 职场文书
母校寄语大全
2014/04/10 职场文书
机电一体化毕业生自荐信
2014/06/19 职场文书
2015年社区中秋节活动总结
2015/03/23 职场文书
Linux中Nginx的防盗链和优化的实现代码
2021/06/20 Servers
MySQL的存储函数与存储过程的区别解析
2022/04/08 MySQL