JavaScript的Map和WeakMap
熟悉JavaScript的Map和WeakMap
Map
Map的键/值可以是任何类型
基本API
初始化映射:
//使用new关键字和Map构造函数进行初始化
const m1 = new Map();
//使用嵌套数组初始化映射
const m2 = new Map([
['k1', 'v1'],
['k2', 'v2'],
['k3', 'v3']
]);
// 使用自定义迭代器初始化
const m3 = new Map({
[Symbol.iterator]:function*() {
yield ['k1', 'v1'];
yield ["k2", "v1"];
yield ["k3", "v3"];
}
})
Map的方法:set()、get()、has()、delete()、clear()
Map的属性:size
m2.set('k4', 'v4');
console.log(m2.has('k4'));//true
console.log(m2.get('k4'));//v4
m2.delete('k4');
console.log(m2.has("k4")); //false
console.log(m2.get("k4"));//undefined
m2.clear();
console.log(m2.has('k1'));//false
set()返回映射实例,于是我们可以链式调用set():
m2.set('k4','v4')
.set('k5','v5');
Map的键的相等比较
键的比较基于零值相等(SameValueZero),它认为+0与-0、NaN与NaN是相等的,其他的所有键通过===来比较相等性。
m2.set(NaN, 1);
m2.set(NaN,2);
console.log(m2.get(NaN));//2
m2.set(-0, 3);
console.log(m2.get(+0));//3
Map和Object的比较
Object也可以用来完成映射的作用,那选Map还是Object呢?
从以下方面决策:
- 内存占用:Object和Map在不同浏览器上的实现有差异,但是都会随着键值对增加占用内存线性增长,同时在给定相同的内存情况下,Map能比Object多存储50%的键值对。
- 插入性能:Map的插入比Object稍微好一点儿。
- 查找速度:如果代码涉及大量查找操作,那么选择Object会更好。
- 删除性能:如果代码涉及大量删除操作,那么选择Map会更好。
- 迭代:Map实现了迭代协议,Object没有。
- size:Map的键值对数量可以通过
size属性轻松获得,而Object只能手动计算。 - 序列化和解析:Map没有序列化和解析支持。
可以实现Map的序列化和解析:How do you JSON.stringify an ES6 Map?
function replacer(key, value) {
if (value instanceof Map) {
return {
dataType: "Map",
value: Array.from(value.entries()), // or with spread: value: [...value]
};
}
return value;
}
function reviver(key, value) {
if (typeof value === "object" && value !== null) {
if (value.dataType === "Map") {
return new Map(value.value);
}
}
return value;
}
const originalValue = new Map([["a", 1]]);
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);
WeakMap
WeakMap称为弱映射。"弱"指的是内存回收机制对待WeakMap中键的方式。
基本API
弱映射的键只能是对象类型(Object或继承自Object)。值类型无限制。
方法和属性的名称和Map相同,除了没有clear()。
弱键
WeakMap中的键不是正式的引用,不会阻止垃圾回收。只要键存在,键值对就会存在于映射中。
const wm = new WeakMap();
wm.set({}, 'v1');

wm新建的键值对的键对象没有被引用,所以垃圾回收机制会回收它。
const wm = new WeakMap();
let obj = new Object();
wm.set(obj, 'v1');
console.log(wm.has(obj));//true
obj = null;
console.log(wm.has(obj));//false
不可迭代键
WeakMap没有提供迭代键值对的功能,也没有必要,是为了保证只有通过键对象的引用才能取得值。
弱映射的实际使用
私有变量
以对象实例为键,以私有成员的字典为值。
const wm = new WeakMap();
class User{
constructor(id) {
this.userId = Symbol('id');
this.setId(id);
}
setId(id) {
const privateMembers = wm.get(this) || {};
privateMembers[this.userId] = id;
wm.set(this, privateMembers);
}
getId() {
return wm.get(this)[this.userId];
}
}
const user = new User(1);
console.log(user.getId());//1
user.setId(2);
console.log(user.getId());//2
上面的变量userId并非真正私有,通过弱映射vm可以获取:
console.log(wm.get(user)[user.userId]);//2
我们可以把弱映射和类放在一个闭包里:
const User = (() => {
const wm = new WeakMap();
class User {
constructor(id) {
this.userId = Symbol("id");
this.setId(id);
}
setId(id) {
const privateMembers = wm.get(this) || {};
privateMembers[this.userId] = id;
wm.set(this, privateMembers);
}
getId() {
return wm.get(this)[this.userId];
}
}
return User;
})();
const user = new User(1);
console.log(user.getId());//1
user.setId(2);
console.log(user.getId());//2
JavaScript的Map和WeakMap的更多相关文章
- javascript之Map
javascript中的map,我用的不是特别多,倒是Java中的Map或HashMap,经常用. 顺便围绕几个方面介绍一下map? 1.Map对象 Map对象是一种有对应键值对的对象,JS的Obje ...
- JavaScript之Map对象
前言 工欲善其事,必先利其器.这是一款以前在前端项目中没有使用过的.有趣的对象,咱来看看如何使用~ 并非arrayObj.map(function) //arrayObj.map与arrayObj.f ...
- Map 和 WeakMap 数据结构
Map 和 WeakMap 是ES6 新增的数据结构 一.Map 它们本质与对象一样,都是键值对的集合,但是他们与 Object 对象主要的不同是,键可以是各种类型的数值,而Object 对象的键 只 ...
- JavaScript之map与parseInt的陷阱
问题来源 这个问题的来源是学习廖雪峰老师JS教程.问题如下:小明希望利用map()把字符串变成整数,他写的代码很简洁: 'use strict'; var arr = ['1', '2', '3' ...
- Map和WeakMap的区别
个人总结:在一个变量作用域中,如果结束到作用域结尾 } 的话,map中的引用会被垃圾回收机制回收的是weakmap ,map中的引用不会被垃圾回收机制回收的是map. 强引用:只要引用存在,垃圾回收器 ...
- javascript自定义Map对象
javascript定义map对象开发前端组件的重要性就不过多阐述了,直接参考以下案例即可 <script type=text/javascript charset=utf-8> func ...
- JavaScript的Map和Set
JavaScript的Map和Set 1.map:映射(通过key获得value).增.删 2.set:增.删.判断是否包含某个元素 1. Map <!DOCTYPE html><h ...
- ES6新增的Map和WeakMap 又是什么玩意?非常详细的解释
上一篇文章讲了set和weakSet,这节咱就讲Map和weakMap是什么?这两篇文章并没有什么联系,主要知识用法类似而已.嘿嘿,是不是感觉舒服多了. 什么是Map 介绍什么是Map,就不得不说起O ...
- Map和WeakMap的方法和区别
Map Map是一组键值对的结构,具有极快的查找速度. 一.构造函数不同 let map = new Map(); let weakmap = new WeakMap(); 二.内置函数不同 Map的 ...
- ES6新特性:Javascript中的Map和WeakMap对象
Map对象 Map对象是一种有对应 键/值 对的对象, JS的Object也是 键/值 对的对象 : ES6中Map相对于Object对象有几个区别: 1:Object对象有原型, 也就是说他有默认的 ...
随机推荐
- 2022-05-06:给你一个整数数组 arr,请你将该数组分隔为长度最多为 k 的一些(连续)子数组。分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值。 返回将数组分隔变换后能够得到的元
2022-05-06:给你一个整数数组 arr,请你将该数组分隔为长度最多为 k 的一些(连续)子数组.分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值. 返回将数组分隔变换后能够得到的元 ...
- 2021-05-22:假设所有字符都是小写字母, 大字符串是str,arr是去重的单词表, 每个单词都不是空字符串且可以使用任意次。使用arr中的单词有多少种拼接str的方式。 返回方法数。
2021-05-22:假设所有字符都是小写字母, 大字符串是str,arr是去重的单词表, 每个单词都不是空字符串且可以使用任意次.使用arr中的单词有多少种拼接str的方式. 返回方法数. 福大大 ...
- [AGC001E] BBQ Hard题解
Problem [AGC001E] BBQ Hard 计算: \[\sum_{i=1}^{n}\sum_{j=i+1}^n\binom{a_i+b_i+a_j+b_j}{a_i+a_j} \] 其中\ ...
- SpringMVC 后台从前端获取单个参数
1.编写web.xml(模板) 2.springmvc配置文件 3.编写对应数据库字段的pojo实体类 @Data @AllArgsConstructor @NoArgsConstructor pub ...
- WPF入门实例 WPF完整例子 WPF DEMO WPF学习完整例子 WPF实战例子 WPF sql实例应用 WPF资料源码
WPF 和 WinForms 都是用于创建 Windows 桌面应用程序的开发框架,它们有一些相似之处,但也有很多不同之处. 在开发速度方面,这取决于具体情况.如果您熟悉 WinForms 开发并且正 ...
- 如何开启Apache SkyWalking的自监控?
1. 开启Prometheus遥测数据 默认情况下, 遥测功能(telemetry)是关闭的(selector 为 none),像这样: telemetry: selector: ${SW_TELEM ...
- LeetCode 周赛 348(2023/06/05)数位 DP 模板学会了吗
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 加入知识星球提问! 往期回顾:LeetCode 单周赛第 347 场 · 二维空间上的 LIS 最长递增子序列问题 ...
- AB实验:科学归因与增长的利器
第一章 AB实验的基本原理和应用 AB实验的相关概念: 3个基本参数:实验参与单元.实验控制参数.实验指标 2个核心价值:验证因果关系.量化策略效果 2个关键特性:先验性.并行性 基本流程:分流 -& ...
- XTTS系列之二:不可忽略的BCT
重要系统Oracle数据库U2L迁移场景中,如果客户来问我建议,我都会回复说首选就是XTTS,除非XTTS经测试实在是无法满足停机窗口,否则就不要考虑OGG这类方案. 换句话说,选择OGG做迁移的场景 ...
- knn和线性分类器
一.knn算法概述 knn首选是最简单的分类算法,其是有监督学习的分类算法之一. 二.knn算法过程 knn(k nearest neighbors k个最近的邻居):knn是当预测一个新的值x的时候 ...