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 相关文章推荐
网页常用特效代码整理
Jun 23 Javascript
IE8提示Invalid procedure call or argument 异常的解决方法
Sep 30 Javascript
js实现简单锁屏功能实例
May 27 Javascript
JS实现网页顶部向下滑出的全国城市切换导航效果
Aug 22 Javascript
一些实用性较高的js方法
Apr 19 Javascript
jQuery+php实时获取及响应文本框输入内容的方法
May 24 Javascript
JavaScript中闭包的写法和作用详解
Jun 29 Javascript
Vue.js每天必学之计算属性computed与$watch
Sep 05 Javascript
jQuery实现的简单排序功能示例【冒泡排序】
Jan 13 Javascript
关于预加载InstantClick的问题解决方法
Sep 12 Javascript
Vue axios 将传递的json数据转为form data的例子
Oct 29 Javascript
微信小程序实现列表滚动头部吸顶的示例代码
Jul 12 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读取大文件示例分享(文件操作类)
2014/04/13 PHP
Linux下php5.4启动脚本
2014/08/03 PHP
php实现有序数组打印或排序的方法【附Python、C及Go语言实现代码】
2016/11/10 PHP
List the Codec Files on a Computer
2007/06/18 Javascript
JavaScript 继承的实现
2009/07/09 Javascript
JavaScript判断窗口是否最小化的代码(跨浏览器)
2010/08/01 Javascript
自写的一个jQuery圆角插件
2010/10/26 Javascript
js 链式延迟执行DOME
2012/01/04 Javascript
通过隐藏iframe实现文件下载的js方法介绍
2014/02/26 Javascript
禁用Enter键表单自动提交实现代码
2014/05/22 Javascript
jquery+css3打造一款ajax分页插件(自写)
2014/06/18 Javascript
显示今天的日期js代码(阳历和农历)
2014/09/30 Javascript
js控制文本框输入的字符类型方法汇总
2015/06/19 Javascript
AngularJs自定义服务之实现签名和加密
2016/08/02 Javascript
bootstrapValidator表单验证插件学习
2016/12/30 Javascript
angularjs ocLazyLoad分步加载js文件实例
2017/01/17 Javascript
如何将 jQuery 从你的 Bootstrap 项目中移除(取而代之使用Vue.js)
2017/07/17 jQuery
vue用BMap百度地图实现即时搜索功能
2019/09/26 Javascript
layui table表格数据的新增,修改,删除,查询,双击获取行数据方式
2019/11/14 Javascript
使用Bootstrap做一个朝代历史表
2019/12/10 Javascript
微信小程序开发搜索功能实现(前端+后端+数据库)
2020/03/04 Javascript
React冒泡和阻止冒泡的应用详解
2020/08/18 Javascript
JavaScript实现简易计算器小功能
2020/10/22 Javascript
[03:13]DOTA2-DPC中国联赛1月25日Recap集锦
2021/03/11 DOTA
以Python的Pyspider为例剖析搜索引擎的网络爬虫实现方法
2015/03/30 Python
python调用Delphi写的Dll代码示例
2017/12/05 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
2017/12/14 Python
Python 循环终止语句的三种方法小结
2019/06/24 Python
python实现图片横向和纵向拼接
2020/03/05 Python
django配置app中的静态文件步骤
2020/03/27 Python
乌克兰在线商店的价格比较:Price.ua
2019/07/26 全球购物
《匆匆》教学反思
2014/02/22 职场文书
第28个世界无烟日活动总结
2015/02/10 职场文书
应聘教师自荐信
2015/03/26 职场文书
亮剑观后感
2015/06/05 职场文书
python实现简单的名片管理系统
2021/04/26 Python