🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 一、Map &emsp;&emsp;Map类似于Object(对象),可用来存储键值对,但需要通过SameValueZero算法保持键的唯一性。与Set一样,在使用之前也得要实例化,如下代码所示,构造函数Map()中的参数也是一个可选的可迭代对象,但此对象得是键值对的集合或两列的二维数组。 ~~~ new Map();        //Map(0) {} new Map([["name", "strick"], ["age", 28]]); //Map(2) {"name" => "strick", "age" => 28} ~~~ **1)属性和方法** &emsp;&emsp;Map比Set多一个读取方法:get(),并且写入方法改成了set(),其它的属性和方法在功能上基本都一致,只是有些参数在含义上略有不同,例如delete()的参数表示键而不是值。方法的具体使用,可参加下面的代码。 ~~~ var people = new Map(); //写入和读取 people.set("name", "strick").set("age", 28);  //Map(2) {"name" => "strick", "age" => 28} people.get("name");               //"strick" people.size;                   //2 //遍历 [...people.keys()]; //["name", "age"] [...people.values()]; //["strick", 28] [...people.entries()]; //[["name", "strick"], ["age", 28]] /* "strick" "name" Map(2) {"name" => "strick", "age" => 28} 28 "age" Map(2) {"name" => "strick", "age" => 28} */ people.forEach(function(value, index, map) { console.log(value, index, map); }); //移除 people.delete("name") people.has("name"); //false people.clear(); people.has("age"); //false ~~~ **2)比较对象** &emsp;&emsp;本节开篇就提到Map和Object很类似,但其实两者之间还是有一些很重要的区别,具体如表10所列。 :-: ![](https://box.kancloud.cn/30b106e613e0bdeecceee576e54a75d8_600x424.png) :-: 表10 Map和Object的对比 ## 二、WeakMap &emsp;&emsp;WeakMap是Map的变体,也是键值对的集合,但它的键必须是弱引用的对象,并且不可枚举,而值没有限制,还是保持任意类型。当WeakMap的键所指的对象不再被引用时,其键和值将被GC自动回收。 **1)创建和方法** &emsp;&emsp;WeakSet也需要像Map那样实例化(如下代码所示),但没有Map的size属性,并且只包含Map中的四个方法:set()、get()、has()和delete(),诸如清空和遍历相关的方法都是不存在的。 ~~~ var weak = new WeakMap(), arr = [1]; weak.set(arr, 10); //WeakMap {Array(1) => 10} weak.get(arr); //10 weak.has(arr); //true weak.delete(arr); weak.has(arr); //false ~~~ **2)用途** &emsp;&emsp;WeakMap的主要优势在于不干扰垃圾收集,从而能够有效的防止内存泄漏。它适用于隐藏信息、存储DOM节点等场景。下面是一个隐藏信息的示例,privates变量是一个WeakMap,它的键是当前实例化的People对象,存储的私有数据是一个对象,两个原型方法分别用于写入和读取name属性。 ~~~ var people = (function() { var privates = new WeakMap(); function People() { privates.set(this, {}); //初始化私有数据 } People.prototype.setName = function(name) { privates.get(this).name = name; //写入 }; People.prototype.getName = function() { return privates.get(this).name; //读取 }; return new People(); })(); people.setName("strick"); people.getName();   //"strick" ~~~ &emsp;&emsp;这种存储方式不仅能让数据保持私有状态,并且当与之关联的对象实例被销毁后,这些私有数据将被GC一并删除,从而释放内存。 &emsp;&emsp;下面是另一个存储DOM节点的示例,node变量是一个WeakMap,它的键是文档中的元素(即DOM的一个节点),在该元素的事件处理程序中可更新digit属性。当从文档中移除该元素时,与之关联的数据也会随之被删除。 ~~~ <div id="container"></div> <script> var container = document.getElementById("container"); var node = new WeakMap(); node.set(container, { digit: 0 }); container.addEventListener("click", function() { var current = node.get(this); current.digit++; node.set(this, current); }, false ); </script> ~~~ ***** > 原文出处: [博客园-ES6躬行记](https://www.cnblogs.com/strick/category/1372951.html) [知乎专栏-ES6躬行记](https://zhuanlan.zhihu.com/pwes6) 已建立一个微信前端交流群,如要进群,请先加微信号freedom20180706或扫描下面的二维码,请求中需注明“看云加群”,在通过请求后就会把你拉进来。还搜集整理了一套[面试资料](https://github.com/pwstrick/daily),欢迎浏览。 ![](https://box.kancloud.cn/2e1f8ecf9512ecdd2fcaae8250e7d48a_430x430.jpg =200x200) 推荐一款前端监控脚本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不仅能监控前端的错误、通信、打印等行为,还能计算各类性能参数,包括 FMP、LCP、FP 等。