Map与WeakMap

Map对象用来保存键值对,并且能够记住键的原始插入顺序,任何对象或者原始值都可以作为键或者是值。
WeakMap对象同样用来保存键值对,对于键是弱引用的而且必须为一个对象,而值可以是任意的对象或者原始值。

Map

描述

Map对象类似于一个普通的键值对的Object对象,也是键值对的集合,但是他们之间有一些重要的区别:

描述 Map Object
意外的键 Map默认情况不包含任何键,只包含显式插入的键。 一个Object有一个原型, 原型链上的键名有可能和在对象上的设置的键名产生冲突。
键的类型 一个Map的键可以是任意值,包括函数、对象或任意基本类型。 一个Object 的键必须是一个String或是Symbol
键的顺序 Map中的key是有序的,当迭代的时候,一个Map对象以插入的顺序返回键值。 一个Object的键的迭代顺序需要通过键的类型与创建的顺序来确定。
键值数量 Map的键值对个数可以轻易地通过size属性获取。 Object的键值对个数只能手动计算。
迭代 Mapiterable的,所以可以直接被迭代。 迭代一个Object需要以某种方式获取它的键然后才能迭代。
性能 Map在频繁增删键值对的场景下表现更好。 Object在频繁添加和删除键值对的场景下未作出优化。

注:关于一个Object的键的迭代顺序问题,在ES6以后,对象保留了StringSymbol的创建顺序,当创建的对象仅有String或者Symbol时,迭代顺序与创建顺序相同,当对象中两种类型都存在时,String总是在前,当String可以被转换为Number时,这些键在迭代时处于最前,且会按照数字的顺序进行迭代。

属性与方法

  • Map.prototype.constructor: 返回构造函数。
  • Map.prototype.size: 返回Map对象的键值对的数量。
  • Map.prototype.clear(): 移除Map对象的所有键值对 。
  • Map.prototype.delete(key): 如果Map对象中存在该元素,则移除它并返回true,否则如果该元素不存在则返回 false
  • Map.prototype.entries(): 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的[key, value]数组。
  • Map.prototype.forEach(callback[, thisArg]): 按插入顺序,为Map对象里的每一键值对调用一次callback函数,如果为forEach提供了thisArg,它将在每次回调中作为this值。
  • Map.prototype.get(key): 返回键对应的值,如果不存在,则返回undefined
  • Map.prototype.has(key): 返回一个布尔值,表示Map实例是否包含键对应的值。
  • Map.prototype.keys(): 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的键。
  • Map.prototype.set(key, value): 设置Map对象中键的值,返回该Map对象。
  • Map.prototype.values(): 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的值。
  • Map.prototype[@@iterator](): 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的[key, value]数组。

示例

var m = new Map();var stringKey = "s";
var objectKey = {};m.set(stringKey, "stringValue");
m.set(objectKey, "objectValue");console.log(m.size); // 2console.log(m.get(stringKey)); // stringValue
console.log(m.get(objectKey)); // objectValuefor (let [key, value] of m) {console.log(key, value);
}
/*s stringValue{} objectValue
*/var m2 = new Map([["stringKey", "stringValue"],[{}, "objectValue"]
]);
console.log(m2); // Map(2) {"stringKey" => "stringValue", {…} => "objectValue"}var m3 = new Map([...m,...m2,["stringKey", "coverStringValue"],[{}, "{} !== {}"],[NaN, "NaN !== NaN But key(NaN) === key(NaN)"],[NaN, "NaN !== NaN But key(NaN) === key(NaN)"],
]);
console.log(m3); // Map(6) {"s" => "stringValue", {…} => "objectValue", "stringKey" => "coverStringValue", {…} => "objectValue", {…} => "{} !== {}", NaN => "NaN !== NaN But key(NaN) === key(NaN)"}

WeakMap

描述

WeakMapkey只能是Object类型,原始数据类型不能作为keyWeakMap持有的是每个键对象的弱引用,这意味着在没有其他引用存在时垃圾回收能正确进行,WeakMap用于映射的key只有在其没有被回收时才是有效的,正由于弱引用,WeakMapkey是不可枚举的,没有方法能给出所有的key
简单来说,有时需要在某个对象上面存放一些对象,但是这会形成对于这个对象的引用,一旦不再需要这个对象,我们就必须手动删除这个引用,否则垃圾回收机制无法释放对象占用的内存,WeakMap的设计就是解决这个问题的,它的键所引用的对象都是弱引用,垃圾回收机制不将该引用考虑在内,因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存,此时WeakMap里边所对应的键值都会消失,不需要手动删除引用。如果需要在对象上添加对象而又不想干扰垃圾回收机制的话,就可以使用WeakMap

属性与方法

  • WeakMap.prototype.constructor: 返回构造函数。
  • WeakMap.prototype.delete(key): 移除key的关联对象。
  • WeakMap.prototype.get(key): 返回key关联对象,没有key关联对象时返回undefined
  • WeakMap.prototype.has(key): 根据是否有key关联对象返回一个Boolean值。
  • WeakMap.prototype.set(key, value): 在WeakMap中设置一组key关联对象,返回这个 WeakMap对象。

内存回收实例

// WeakMap示例代码
var wm = new WeakMap();
var key = {};
wm.set(key, new Array(6 * 1024 * 1024)); // 存放一个大数组
console.log(wm.get(key)); // (6291456) [empty × 6291456]
key = null;
console.log(wm.get(key)); // undefined
// WeakMap内存回收实例
/** node --expose-gc **/ // 启动node环境 手动调用垃圾回收机制
global.gc(); // 首先调用一次垃圾回收
process.memoryUsage(); // 查看内存占用 heapUsed约2M
/*{rss: 21975040,heapTotal: 4608000,heapUsed: 2454040,external: 1384318}
*/
var wm = new WeakMap();
var key = {};
wm.set(key, new Array(6 * 1024 * 1024)); // 存放一个大数组
console.log(wm.get(key)); // (6291456) [empty × 6291456]
process.memoryUsage(); // heapUsed约53M
/*{rss: 73420800,heapTotal: 55259136,heapUsed: 53060600,external: 1384408}
*/
global.gc(); // 手动执行一次垃圾回收
process.memoryUsage(); // heapUsed约53M
/*{rss: 73302016,heapTotal: 55259136,heapUsed: 52637112,external: 1384350}
*/
key = null; // 解除引用
global.gc(); // 执行垃圾回收
process.memoryUsage(); // heapUsed约2M 内存已回收
/*{rss: 23142400,heapTotal: 4923392,heapUsed: 2674536,external: 1384445}
*/
console.log(wm.get(key)); // undefined
// Map示例代码 对比
var m = new Map();
var key = {};
m.set(key, new Array(6 * 1024 * 1024)); // 存放一个大数组
console.log(m.get(key)); // (6291456) [empty × 6291456]
key = null;
console.log(m.get(key)); // undefined
console.log(m); // Map(1) {{…} => Array(6291456)}
m.clear(); // 回收内存
console.log(m); // Map(0) {}
// Map内存回收实例 对比
/** node --expose-gc **/ // 启动node环境 手动调用垃圾回收机制
global.gc(); // 首先调用一次垃圾回收
process.memoryUsage(); // 查看内存占用 heapUsed约2M
/*{rss: 21856256,heapTotal: 4608000,heapUsed: 2460600,external: 1384318}
*/
var m = new Map();
var key = {};
m.set(key, new Array(6 * 1024 * 1024)); // 存放一个大数组
console.log(m.get(key)); // (6291456) [empty × 6291456]
process.memoryUsage(); // heapUsed约53M
/*{rss: 73744384,heapTotal: 55521280,heapUsed: 53703816,external: 1384504}
*/
global.gc(); // 手动执行一次垃圾回收
process.memoryUsage(); // heapUsed约53M
/*{rss: 73125888,heapTotal: 55521280,heapUsed: 53135936,external: 1384350}
*/
key = null; // 解除引用
global.gc(); // 执行垃圾回收
process.memoryUsage(); // heapUsed约53M 内存未回收
/*{rss: 73093120,heapTotal: 55521280,heapUsed: 52960672,external: 1384350}
*/
console.log(m.get(key)); // undefined // 此处是undefined,这是因为key值的改变,而在这个Map实例对象中依然存在 {} => Array 的键值对,且键值对为强引用,内存未回收
console.log(m); // Map(1) {{…} => Array(6291456)}
m.clear(); // 回收内存
global.gc(); // 执行垃圾回收
process.memoryUsage(); // heapUsed约2M 内存已回收
/*{rss: 22908928,heapTotal: 5185536,heapUsed: 2627064,external: 1384350}
*/
console.log(m); // Map(0) {}

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://blog.csdn.net/c__dreamer/article/details/82182649
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakMap

Map与WeakMap相关推荐

  1. 第十七节:ES6新增的Map和WeakMap 又是什么东西?

    上节介绍了Set和WeakSet,这节咱就讲Map和WeakMap是什么?当然,两者之前并没什么必然的联系,仅仅是用法类似. 什么是Map 介绍什么是Map,就不得不说起Object对象,我们都知道O ...

  2. Map 和 WeakMap

    Map 和 WeakMap Map map对象是一个简单的键/值映射.任何值(包括对象和原始值)都可以用作一个键或一个值. var m = new Map(); var o = {p: "H ...

  3. ES6 中的 Set、Map 和 WeakMap

    ES6 新增了几种集合类型,本文介绍 Set.Map 和 WeakMap.比较新的 Firefox.Chrome(需要在 about:flags 启用实验性 JavaScript)以及 IE11 都有 ...

  4. ES6——Map和WeakMap

    ES6 提供了新的数据结构 Map. 它有九个常用方法: 通过键检查元素是否存在 has(key) 添加元素 set(key , value) 通过键移除元素 delete(key) 通过键获取值 g ...

  5. 【ES6基础】Map与WeakMap

    开篇 ES6里除了增加了Set(集合)类型外(笔者在这篇文章<Set与WeakSet>有过介绍),今天的这篇文章笔者将继续介绍ES6引入的新类型--Map(映射类型)和其对应的弱类型Wea ...

  6. 初探ES6中的Map和WeakMap

    Map 对象保存键值对.任何值(对象或者原始值) 都可以作为一个键或一个值. 使用映射对象 let myMap=new Map(); let keyObj={},keyfunc=function(){ ...

  7. ES6(三)——Set、WeakSet、Map、WeakMap

    一.Set的基本使用 在ES6之前,我们存储数据的结构主要有两种:数组.对象. 在ES6中新增了另外两种数据结构:Set.Map,以及它们的另外形式WeakSet.WeakMap. Set是一个新增的 ...

  8. set和map去重调用什么方法_你真的了解ES6的Set,WeakSet,Map和WeakMap吗?

    之前在学习 ES6 的时候,看到 Set 和 Map,不知道其应用场景有哪些,只觉得很多时候会用在数组去重和数据存储,后来慢慢才领悟到 Set 是一种叫做集合的数据结构,Map 是一种叫做字典的数据结 ...

  9. map与weakmap,ES6 Map和WeakMap有什么区别?

    Looking this and this MDN pages it seems like the only difference between Maps and WeakMaps is a mis ...

最新文章

  1. php发卡_发卡网代码审计
  2. EXT.NET复杂布局(四)——系统首页设计(下)
  3. linux 编译git 客户端源码然后安装
  4. spark调用python程序包_pycharm编写spark程序,导入pyspark包的3中实现方法
  5. 语音识别几成标配,哈弗F7的智能语音系统有何不同?
  6. python day33
  7. AntPathMatcher路径匹配器,Ant风格的URL
  8. 粥左罗教你从零开始学写作笔记系列
  9. java中choice用法,批处理中choice用法
  10. 免费的网页截屏API有哪些?
  11. 想学大数据?先看完这几本书再说
  12. DecoupleSegNets学习总结
  13. Threejs实现宇宙中地球动态展示和卫星绕地运动
  14. Python全栈-magedu-2018-笔记13
  15. Cortex-M3 处理器内核
  16. python笔记---(实验二)
  17. vmware如果已在BIOS/固件设置中禁用IntelVT-x,或主机自更改此设置后从未重新启动,则IntelVT-x
  18. Maven 环境踩坑及完整配置
  19. leetcode--计算质数(素数)
  20. linux实验三:基于mykernel 2.0编写一个简单的操作系统内核

热门文章

  1. istio多集群链路追踪,附实操视频
  2. idea中查看maven信息
  3. UserDetailsService详解
  4. springcloud 使用git作为配置中心
  5. DownloadManager不好用?试试ZlsamDownloadService
  6. 深究Spring中Bean的生命周期
  7. Linux nc命令详解
  8. 全新Wijmo5中文学习指南正式上线
  9. VBA调用DOS程序两种方法
  10. CES神吐槽:人工智能快要“烂大街”了?