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 跨域和ajax 跨域问题小结
Jul 01 Javascript
JQuery CSS样式控制 学习笔记
Jul 23 Javascript
javaScript 关闭浏览器 (不弹出提示框)
Jan 31 Javascript
js querySelector和getElementById通过id获取元素的区别
Apr 20 Javascript
js实现弹窗插件功能实例代码分享
Dec 12 Javascript
jQuery DOM操作实例
Mar 05 Javascript
iframe实用操作锦集
Apr 22 Javascript
jQuery 计算iframe 窗口大小的方法
May 13 Javascript
浅析javascript函数表达式
Feb 10 Javascript
vue-cli+webpack记事本项目创建
Apr 01 Javascript
详解.vue文件中style标签的几个标识符
Jul 17 Javascript
小程序实现列表删除功能
Oct 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加速的eAccelerator dll支持文件打包下载
2007/09/30 PHP
php 数组随机取值的简单实例
2016/05/23 PHP
Laravel使用scout集成elasticsearch做全文搜索的实现方法
2018/11/30 PHP
CI框架实现创建自定义类库的方法
2018/12/25 PHP
不错的一个日期输入 动态
2006/11/06 Javascript
js静态方法与实例方法分析
2011/07/04 Javascript
js关闭浏览器窗口及检查浏览器关闭事件
2013/09/03 Javascript
JS+DIV实现鼠标划过切换层效果的实例代码
2013/11/26 Javascript
使用javascript控制cookie显示和隐藏背景图
2014/02/12 Javascript
借助javascript代码判断网页是静态还是伪静态
2014/05/05 Javascript
浅谈js中test()函数在正则中的使用
2016/08/19 Javascript
jQuery Easy UI中根据第一个下拉框选中的值设置第二个下拉框是否可以编辑
2016/11/29 Javascript
ajax与json 获取数据并在前台使用简单实例
2017/01/19 Javascript
Vue.js学习之计算属性
2017/01/22 Javascript
Bootstrap学习笔记之进度条、媒体对象实例详解
2017/03/09 Javascript
JS+CSS实现网页加载中的动画效果
2017/10/27 Javascript
js实现数组内数据的上移和下移的实例
2017/11/14 Javascript
JavaScript捕捉事件和阻止冒泡事件实例分析
2018/08/03 Javascript
vue实现多组关键词对应高亮显示功能
2019/07/25 Javascript
vue+element实现动态加载表单
2020/12/13 Vue.js
[02:40]DOTA2英雄基础教程 先知
2013/11/29 DOTA
Python中的getopt函数使用详解
2015/07/28 Python
pygame游戏之旅 添加游戏介绍
2018/11/20 Python
用Pycharm实现鼠标滚轮控制字体大小的方法
2019/01/15 Python
Python查找不限层级Json数据中某个key或者value的路径方式
2020/02/27 Python
Python进程的通信Queue、Pipe实例分析
2020/03/30 Python
分享一个H5原生form表单的checkbox特效代码
2018/02/26 HTML / CSS
哈萨克斯坦最大的时装、鞋子和配饰在线商店:Lamoda.kz
2019/11/19 全球购物
Araks官网:纽约内衣品牌
2020/10/15 全球购物
信息技术专业大学生个人的自我评价
2013/10/05 职场文书
音乐表演专业毕业生求职信
2013/10/14 职场文书
小学生春游活动方案
2014/08/20 职场文书
庆祝三八妇女节标语
2014/10/09 职场文书
超市主管竞聘书
2015/09/15 职场文书
盘点2020年适合农村地区创业的项目
2019/10/16 职场文书
mysql 获取时间方式
2022/03/20 MySQL