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实现动态改变div宽度和高度
May 08 Javascript
快速学习jQuery插件 jquery.validate.js表单验证插件使用方法
Dec 01 Javascript
基于jquery实现动态竖向柱状条特效
Feb 12 Javascript
jquery自定义插件——window的实现【示例代码】
May 06 Javascript
Bootstrap3制作搜索框样式的方法
Jul 11 Javascript
AngularJS通过$http和服务器通信详解
Sep 21 Javascript
jQuery 实现ajax传入参数含有特殊字符的方法总结
Oct 17 Javascript
bootstrap css样式之表单
Jan 19 Javascript
详解vue-cli 构建Vue项目遇到的坑
Aug 30 Javascript
Three.js 再探 - 写一个微信跳一跳极简版游戏
Jan 04 Javascript
如何优雅地在Node应用中进行错误异常处理
Nov 25 Javascript
微信小程序自定义菜单切换栏tabbar组件代码实例
Dec 30 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中的常用函数回顾
2013/07/11 PHP
PHP与javascript实现变量交互的示例代码
2013/07/23 PHP
zf框架的session会话周期及次数限制使用示例
2014/03/13 PHP
Symfony2实现在controller中获取url的方法
2016/03/18 PHP
Smarty模板语法详解
2019/07/20 PHP
Laravel 前端资源配置教程
2019/10/18 PHP
javascript 页面只自动刷新一次
2009/07/10 Javascript
解决表单中第一个非隐藏的元素获得焦点的一个方案
2009/10/26 Javascript
jquery必须知道的一些常用特效方法及使用示例(整理)
2013/06/24 Javascript
javascript中怎么做对象的类型判断
2013/11/11 Javascript
javascript表单验证大全
2015/08/12 Javascript
JavaScript基础知识之方法汇总结
2016/01/24 Javascript
全面了解JavaScript的数据类型转换
2016/07/01 Javascript
jquery实现网页定位导航
2016/08/23 Javascript
详解nodejs 文本操作模块-fs模块(二)
2016/12/22 NodeJs
基于javascript实现数字英文验证码
2017/01/25 Javascript
使用vue构建一个上传图片表单
2017/07/04 Javascript
Node.JS段点续传:Nginx配置文件分段下载功能的实现方法
2018/03/12 Javascript
Vue slot用法(小结)
2018/10/22 Javascript
[01:11:10]2014 DOTA2华西杯精英邀请赛 5 24 iG VS VG加赛
2014/05/26 DOTA
python3简单实现微信爬虫
2015/04/09 Python
一步步教你用Python实现2048小游戏
2017/01/19 Python
对Python subprocess.Popen子进程管道阻塞详解
2018/10/29 Python
Python多图片合并PDF的方法
2019/01/03 Python
python3.6根据m3u8下载mp4视频
2019/06/17 Python
Python画图实现同一结点多个柱状图的示例
2019/07/07 Python
python实现按首字母分类查找功能
2019/10/31 Python
Python多线程操作之互斥锁、递归锁、信号量、事件实例详解
2020/03/24 Python
Python基础教程(一)——Windows搭建开发Python开发环境
2020/07/20 Python
python实现无边框进度条的实例代码
2020/12/30 Python
python用opencv 图像傅里叶变换
2021/01/04 Python
CSS3只让背景图片旋转180度的实现示例
2021/03/09 HTML / CSS
腾讯技术类校园招聘笔试试题
2014/05/06 面试题
党员四风问题个人对照检查材料
2014/10/26 职场文书
机关干部作风整顿心得体会
2016/01/22 职场文书
MyBatis自定义SQL拦截器示例详解
2021/10/24 Java/Android