ES6 集合引用类型 Map 与 WeakMap
简介:
在 ES6 之前,在 JavaScript 中实现‘键’=>‘值’,也就是我们常说的键值对,是用 Object 来完成的。但这种实现方式在特殊场景下的有问题的,ES6 又出了一个为 Map 的新集合类型,为这门语言带来正真的键值对存储机制。
使用 Map
我们可以使用 new 来创建
如果需要在里面添加键值对的话可以使用 set() 方法
另外还可以使用 get()和 has()方法进行查询
还可以通过 size 属性来获取映射中的键值对数量,我们先再添加一个键值对,查询一下数量
我们还可以通过 delete()和 clear()来进行删除
Map 与 Object 的差异
1. 内存占用
Object 和 Map 的工程及实现在不同浏览器间存在很大的差异,如果给固定大小的内存,Map 要比 Object 多存储 50%的键值对。
2.查找速度
大型的 Object 和 Map 中查找键值对的性能差异较小,如果只包含少量的键值对,Object 要比 Map 更块一些,在把 Object 当成数组使用的情况下(比如连续使用整数作为属性)浏览器引擎可以进行优化,这对 Map 操作是不可能的。
3.插入性能
向 Object 和 Map 中插入新的键值对消耗大致差不多,如果代码量涉及的比较多的话,Map 的性能更好一些
4.删除属性
使用 delete 删除 Object 属性的性能在浏览器中一直饱受诟病,有一些人为了删除对象属性会把属性值设为 null 和 undefined。而 Map 的 delete 操作要比插入和查询都快,如果涉及大量代码的话,Map 肯定是最优选。
weakMap
什么是 WeakMap
在 JavaScript 里,map API 可以通过使其四个 API 方法共用两个数组(一个存放键,一个存放值)来实现。给这种 map 设置值时会同时将键和值添加到这两个数组的末尾。从而使得键和值的索引在两个数组中相对应。当从该 map 取值的时候,需要遍历所有的键,然后使用索引从存储值的数组中检索出相应的值。
但这样的实现会有两个很大的缺点,首先赋值和搜索操作都是 O(n) 的时间复杂度( n 是键值对的个数),因为这两个操作都需要遍历全部整个数组来进行匹配。另外一个缺点是可能会导致内存泄漏,因为数组会一直引用着每个键和值。这种引用使得垃圾回收算法不能回收处理他们,即使没有其他任何引用存在了。
相比之下,原生的 WeakMap 持有的是每个键对象的“弱引用”,这意味着在没有其他引用存在时垃圾回收能正确进行。原生 WeakMap 的结构是特殊且有效的,其用于映射的 key 只有在其没有被回收时才是有效的。
正由于这样的弱引用,WeakMap
的 key 是不可枚举的 (没有方法能给出所有的 key)。如果 key 是可枚举的话,其列表将会受垃圾回收机制的影响,从而得到不确定的结果。因此,如果你想要这种类型对象的 key 值的列表,你应该使用 [Map
]
基本上,如果你要往对象上添加数据,又不想干扰垃圾回收机制,就可以使用 WeakMap。
注意
WeakMap 的 key 只能是 Object
类型。 [原始数据类型] 是不能作为 key 的(比如 [Symbol
]。
执行以上代码就会报错,因为 WeakMap 的建只能是对象类型
如果变成 object 类型当作键存储就可以执行
另外 WeakMap 的值也可以是一个对象,但这样没有太大意义
版权声明: 本文为 InfoQ 作者【大熊G】的原创文章。
原文链接:【http://xie.infoq.cn/article/280a5590cc03b2e7fd92127ea】。文章转载请联系作者。
评论