ES6 新增了几种集合类型,本文介绍 Set、Map 和 WeakMap。比较新的 Firefox、Chrome(需要在 about:flags 启用实验性 JavaScript)以及 IE11 都有不同程度的实现。需要注意的是,ES6 规范会一直调整,本文只以当前规范及浏览器实现为准。

Set(数组基础数据去重)

Set 是 ES6 新增的有序列表集合,它不会包含重复项。之前我们通常用对象(Object)或者数组(Array)来实现没有重复项的集合。但对象会对 key 进行 toString() 操作,这会导致某些 key 会意外覆盖之前的数据;如果 key 本身是一个对象,toString() 也得不到想要的结果,如下:

JSvar o = {};var key1 = 2;
var key2 = { toString : function() { return 2 } };var key3 = { x : 1 };
var key4 = { y : 2 };o[key1] = 1;
o[key2] = 2;
o[key3] = 3;
o[key4] = 4;// o : Object {2: 2, [object Object]: 4}

数组可以存放任何类型的数据,不过数据除重需要自己实现。

Set 支持 add(item) 方法,用来向 Set 添加任意类型的元素,如果已经添加过则自动忽略;has(item) 方法用来检测 Set 中是否存在指定元素;delete(item) 方法用来从 Set 中删除指定元素;clear() 用来清空 Set;获取 Set 集合长度用 size 属性。如下:

JSvar set = new Set();
set.add(window);
set.has(window); // true
set.size; // 1
set.add(window);
set.add(1);
set.size; // 2
set.delete(window);
set.has(window); // false
set.clear();
set.size; // 0

Set 调用 add、has、delete 等方法时对 key 进行的比较,不做类型转换。可以认为使用「===」进行比较,当然也不全是「===」:

  • Set 中,NaN 只能添加一次(虽然NaN === NaN 返回 false);
  • Set 中,「-0」和「0 或 +0」可以同时存在,因为符号不一样(虽然 -0 === 0 或 -0 === +0 返回 true);

Map(有序键值对集合)

Map 是 ES6 新增的有序键值对集合。键值对的 key 和 value 都可以是任何类型的元素。通过 set(key, value) 方法为 Map 设置新的键值对,如果设置的 key 已经存在则用新的 value 覆盖,Map 在比较 key 时也不做类型转换,跟 Set 类似;Map 的 get(key) 方法用来获取指定 key 的值;Map 的 has(key) 、 delete(key) 、clear() 这些方法和 size 属性,与 Set 类似,直接看代码:

JSvar map = new Map();
var key1 = {toString : function() { return 2}};
var key2 = 2;
map.set(key1, 1);
map.set(key2, 2);map.has(key1); // true
map.has('2'); // false,类型不同
map.delete(2);
map.size; // 1
map.get(key2); // undefined

迭代

我们没办法像数组一样用 for 循环来迭代 Set,也没办法像对象一样用 for...in 来迭代 Map。但是可以用 ES6 提供的新方法 for...of 来遍历它们。

Set 和 Map 有几个方法会返回可迭代对象(Iterator Objects),分别是 entries()、keys() 和 values()。直接遍历 Set/Map,等同于遍历 entries();keys() 和 values() 则分别返回 key 和 value 的集合;对于 Set,key 和 value 是一样的。这些方法和 for...of 现阶段都只有 Firefox 支持,下面的例子需要在 Firefox 下运行:

JSvar set = new Set();
set.add('this is a demo.');
set.add(window);
set.add(top);for(let item of set) {console.log(item);
}

WeakMap(非空键值对集合)

WeakMap 相对于普通的 Map,也是键值对集合,只不过 WeakMap 的 key 只能是非空对象(non-null object)。WeakMap 对它的 key 仅保持弱引用,也就是说它不阻止垃圾回收器回收它所引用的 key。WeakMap 最大的好处是可以避免内存泄漏。一个仅被 WeakMap 作为 key 而引用的对象,会被垃圾回收器回收掉。

WeakMap 拥有和 Map 类似的 set(key, value) 、get(key)、has(key)、delete(key) 和 clear() 方法,但没有 size 属性,也没有任何与迭代有关的方法。

为了演示 WeakMap 与内存回收的关系,我用 IE11 做了一个简单的测试。IE11 的 F12 开发者工具改进很大,下次找机会单独介绍。测试流程如下:

  1. 创建一个全局的 Map/WeakMap 对象;
  2. 进入局部作用域,创建大量对象作为 key,加到 Map/WeakMap 中;
  3. 离开局部作用域,检查第 2 步创建的大量对象是否被回收;
  4. 手动回收 Map/WeakMap 对象;

内存使用结果如下:

红线位置即为测试的第 2 步,可以看到给 Map/WeakMap 添加大量对象后,内存使用大幅增加;但 WeakMap 没有阻止这些对象随后被回收,内存使用马上跌落,与 Map 对比非常明显;最后手动回收 Map/WeakMap 之后,全部内存都会被回收。

WeakSet?

ES6 还定义了另外一种集合类型:WeakSet,但目前还没有浏览器实现。顾名思义,它应该是没有 size 属性、不能迭代的 Set;且只能添加非空对象。这里有 V8 引擎实现 WeakSet 的代码,可以先看看。

转载于:https://www.cnblogs.com/EnSnail/p/6930327.html

ES6 中的 Set、Map 和 WeakMap相关推荐

  1. php 数据类型 map,es6中Set和Map的对比介绍(附代码)

    本篇文章给大家带来的内容是关于es6中Set和Map的对比介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. Set 1.add()方法和size属性{ let list ...

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

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

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

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

  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和Set详解

    概览 本文主要介绍了 ES6新增的Set和Map 数据结构,对其特性和常见用法进行了梳理 一. Set Set是ES6中新增的数据结构,它类似于数组,但是Set数据中的元素都是唯一的,没有重复值的; ...

  7. es6中的map方法

    es6中的map方法 一.简单的说明 map是一种数据结构,类似于对象,但是里面的键的值可以是各种类型,包括对象也行 //声明Maplet m = new Map();m.set('name','zh ...

  8. 什么?ES6 中还有 Tail Calls!

    前言 先吐槽一件事,最近把原先的 TOP 域名更换到 CN 域名,并且用 Gatsby 重建个人站点,之前是用采用 HTTPS 部署的方式绕过阿里云的域名备案系统.更换 CN 域名后,这招不管用了,? ...

  9. ES6中的新特性:Iterables和iterators

    文章目录 简介 什么是iteration Iterable对象 普通对象不是可遍历的 自定义iterables 关闭iterators 总结 简介 为了方便集合数据的遍历,在ES6中引入了一个iter ...

最新文章

  1. “Jupyter的杀手”:Netflix发布新开发工具Polynote
  2. 3文件提取器_eMail Address Extractor for Mac(邮件地址提取器)
  3. BTC 缓步推升,BCH 再拔头筹
  4. 实验三——vlan间路由
  5. 2.4.安装spaCy
  6. 020303阶段三 I/O复用 select和epoll的文件描述符管理
  7. 利用Scala特征(trait)的堆叠操作特性进行切面编程
  8. Centos 6.4使用本地yum源
  9. 从零开始编写深度学习库(五)ConvolutionLayer CPU编写
  10. “苹果正在走下神坛” | 畅言
  11. Multisim 14.1 安装步骤
  12. 浅谈Android中的MVP架构
  13. 小程序各领域的代表出来溜大街了
  14. 阿里云CDN是什么意思?
  15. 计算机课程老师讲什么初中,初中计算机老师的教学工作总结
  16. 一个游戏程序员的学习资料【转】
  17. 7-4 sdust-Java-学生成绩读取与排序 (35分)CSDN-markdown编辑器
  18. 实验五 汉字字库实验(Logisim)
  19. 计算机中丢失MSVCR120.dll,电脑找不到MSVCR120.dll怎么办
  20. 深入中英文的排版与换行

热门文章

  1. bower 和 npm 的区别
  2. node.js学习之react,redux,react-redux
  3. Conference Related to social network.
  4. C语言版回字四种写法的一个例子——数组下标访问
  5. 剪切粘贴时总是上次的内容_关于复制粘贴,还有一个鲜为人知的技巧!
  6. pythongoogle.probuf.timestamp_gRPC快速入门(一)——Protobuf简介
  7. idea 修改样式要编译_在IDEA中DEBUG Javac源码
  8. Python机器学习:KNN算法05f超参数
  9. odbc如何连oracle数据库,不安装Oracle如何连数据库(odbc驱动)
  10. linux7空闲内存,centos7 内存占用率高处理问题