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 20 Javascript
JS随机调用指定函数的方法
Jul 01 Javascript
jQuery+CSS3折叠卡片式下拉列表框实现效果
Nov 02 Javascript
分享jQuery封装好的一些常用操作
Jul 28 Javascript
AngularJS ng-repeat指令中使用track by子语句解决重复数据遍历错误问题
Jan 21 Javascript
JavaScript函数表达式详解及实例
May 05 Javascript
vue-cli构建项目下使用微信分享功能
May 28 Javascript
js form表单input框限制20个字符,10个汉字代码实例
Apr 12 Javascript
ES6 Object方法扩展的应用实例分析
Jun 25 Javascript
layui实现左侧菜单点击右侧内容区显示
Jul 26 Javascript
vue使用swiper.js重叠轮播组建样式
Nov 14 Javascript
微信小程序 flexbox layout快速实现基本布局的解决方案
Mar 24 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 递归效率分析
2009/11/24 PHP
PHP正确解析UTF-8字符串技巧应用
2012/11/07 PHP
php实现图形显示Ip地址的代码及注释
2014/01/20 PHP
php上传图片存入数据库示例分享
2014/03/11 PHP
php实现比较两个字符串日期大小的方法
2015/05/12 PHP
php实现网站文件批量压缩下载功能
2015/10/28 PHP
laravel 执行迁移回滚示例
2019/10/23 PHP
深入浅析安装PhpStorm并激活的步骤详解
2020/09/17 PHP
MSN消息提示类
2006/09/05 Javascript
可以将word转成html的js代码
2010/04/11 Javascript
dess中一个简单的多路委托的实现
2010/07/20 Javascript
js判断url是否有效的两种方法
2014/03/04 Javascript
Javascript 运动中Offset的bug解决方案
2014/12/24 Javascript
微信小程序wx.previewImage预览图片实例详解
2017/12/07 Javascript
ajax请求data遇到的问题分析
2018/01/18 Javascript
js传递数组参数到后台controller的方法
2018/03/29 Javascript
Vue单页应用引用单独的样式文件的两种方式
2018/03/30 Javascript
js验证身份证号码记录的方法
2019/04/26 Javascript
[29:10]Ti4 冒泡赛第二天 NEWBEE vs Titan 3
2014/07/15 DOTA
python在线编译器的简单原理及简单实现代码
2018/02/02 Python
Python 3.6 读取并操作文件内容的实例
2018/04/23 Python
pandas的qcut()方法详解
2019/07/06 Python
关于python导入模块import与常见的模块详解
2019/08/28 Python
在Django下测试与调试REST API的方法详解
2019/08/29 Python
pygame实现成语填空游戏
2019/10/29 Python
基于Django统计博客文章阅读量
2019/10/29 Python
什么是Python中的匿名函数
2020/06/02 Python
英国最大的香水商店:The Fragrance Shop
2018/07/06 全球购物
Travelstart沙特阿拉伯:廉价航班、豪华酒店和实惠的汽车租赁优惠
2019/04/06 全球购物
如果让你测试一台高速激光打印机,你都会进行哪些测试
2012/12/04 面试题
中专毕业生的自我鉴定
2013/12/01 职场文书
培训心得体会
2013/12/29 职场文书
《水乡歌》教学反思
2014/04/24 职场文书
运动会致辞稿
2015/07/29 职场文书
2016年第二十届“母亲节暨幸福工程救助贫困母亲活动日”活动总结
2016/04/06 职场文书
详解Go语言运用广度优先搜索走迷宫
2021/06/23 Python