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 遍历- 关于closest() 的方法介绍以及与parents()的方法区别分析
Apr 26 Javascript
JS获取DropDownList的value值与text值的示例代码
Jan 07 Javascript
js中跨域方法原理详解
Jul 19 Javascript
javascript适合移动端的日期时间拾取器
Nov 10 Javascript
JavaScript的this关键字的理解
Jun 18 Javascript
Ext JS动态加载JavaScript创建窗体的方法
Jun 23 Javascript
js 动态添加元素(div、li、img等)及设置属性的方法
Jul 19 Javascript
使用 jQuery.ajax 上传带文件的表单遇到的问题
Oct 31 Javascript
vue实现a标签点击高亮方法
Mar 17 Javascript
详解vue-router 命名路由和命名视图
Jun 01 Javascript
JavaScript工具库之Lodash详解
Jun 15 Javascript
vue中的计算属性和侦听属性
Nov 06 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开发模式(简写版)
2007/03/15 PHP
PHP 可阅读随机字符串代码
2010/05/26 PHP
PHP mcrypt可逆加密算法分析
2011/07/19 PHP
discuz图片顺序混乱解决方案
2015/07/29 PHP
Laravel 5.5 实现禁用用户注册示例
2019/10/24 PHP
javascript Array数组对象的扩展函数代码
2010/05/22 Javascript
jQuery操作input值的各种方法总结
2013/11/21 Javascript
javascript模拟订火车票和退票示例
2014/04/24 Javascript
jQuery插件jPaginate实现无刷新分页
2015/05/04 Javascript
AngularJS中的过滤器使用详解
2015/06/16 Javascript
在Docker快速部署Node.js应用的详细步骤
2016/09/02 Javascript
jQuery post数据至ashx实例详解
2016/11/18 Javascript
Javascript中八种遍历方法的执行速度深度对比
2017/04/25 Javascript
Node.js 的模块知识汇总
2017/08/16 Javascript
解决vue项目打包后提示图片文件路径错误的问题
2018/07/04 Javascript
jQuery实现的点击按钮改变样式功能示例
2018/07/21 jQuery
浅谈一种让小程序支持JSX语法的新思路
2019/06/16 Javascript
微信小程序顶部导航栏可滑动并选中放大
2019/12/05 Javascript
[01:03:22]LGD vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
Python continue语句用法实例
2014/03/11 Python
使用IronPython把Python脚本集成到.NET程序中的教程
2015/03/31 Python
python统计文本字符串里单词出现频率的方法
2015/05/26 Python
Python常用的内置序列结构(列表、元组、字典)学习笔记
2016/07/08 Python
python中单例常用的几种实现方法总结
2018/10/13 Python
python使用selenium登录QQ邮箱(附带滑动解锁)
2019/01/23 Python
python 计算两个列表的相关系数的实现
2019/08/29 Python
树莓派安装OpenCV3完整过程的实现
2019/10/10 Python
使用 Python 写一个简易的抽奖程序
2019/12/08 Python
Pytorch之view及view_as使用详解
2019/12/31 Python
理想演讲稿范文
2014/05/21 职场文书
2014年世界艾滋病日演讲稿
2014/11/28 职场文书
2014年基建工作总结
2014/12/12 职场文书
七年级上册语文教学计划
2015/01/22 职场文书
部队个人年终总结
2015/03/02 职场文书
项目技术负责人岗位职责
2015/04/13 职场文书
大学生暑期实践报告之企业经营管理
2019/08/08 职场文书