ES6 中的 Map和Set
集合的概念以及和数组的区别
其实数组也是集合, 只不过数组的索引是数值类型.当想用非数值类型作为索引时, 数组就无法满足需要了.
而 Map 集合可以保存多个键-值对(key-value), Set 集合可以保存多个元素.
对Map 和 Set 一般不会逐一遍历其中的元素. Map 一般用来存储需要频繁取用的数据, Set 一般用来判断某个值是否存在其中.
ES 5 中对 Map 和 Set 的模拟方法
在ES 5 中,没有 Set和Map集合, 一般使用对象来模拟这两种集合, 对象的属性作为键(key), 以属性值作为值(value), 即以 property: property-value
来模拟 key-value
的形式. 具体实现如下:
模拟 Map 的键值对集合:
// 创建一个 Map 对象
var map = Object.create(null);
// 添加属性和属性值, 即 添加 key 和 value
map.key1 = 'value 1';
map.key2 = {};
// 取得 key 对应的 value
console.log(map.key1); // "value 1"
console.log(map.key2); // "Object {}"
模拟 Set :
// 创建一个 Set 对象
var set = Object.create(null);
// 添加属性和属性值, 即 添加 key 并令其值为 true, 即表示这个key存在于集合中
set.key = true;
// 判断 key 是否存在, 然后进行下一步的操作
if(set.key) { ... }
用对象模拟这两种集合的缺陷
- 由于对象中的属性名必须是字符串, 如果传入的不是字符串则会强制转换成对应的字符串类型(强制转换方面的知识可以看这篇文章点击)
- 一般使用 if 语句来判断一个 key 是否存在于集合中, 当这个 key 对应的 value 为 false 或者可以被强制转换为 false 时, 则 if 语句认为这个key不存在.但是其实是存在的, 只不过 value = false 而已.
ES6 中的 Map 和 Set 集合
下面正式来讨论这两种集合的特点
Map
Map 中存储的是 key-value 形式的键值对, 其中的 key 和 value 可以是任何类型的, 即对象也可以作为 key . 这比用对象来模拟的方式就灵活了很多
Map 的创建和初始化
- 可以用new Map()构造函数来创建一个空的 Map
// 创建一个空的 Map
let map = new Map();
- 也可以在 Map() 构造函数中传入一个数组来创建并初始化一个 Map. 传入的数组是二维数组, 其中的每一个子数组都有两个元素, 前者会被作为 key, 后者会被作为 value, 这样就形成了一个 key-value 键值对. 例如:
// 用数组来创建一个 非空的 Map
let array = [ // 定义一个二维数组, 数组中的每子都有两个元素
['key1' , 'value 1'], // key 是 字符串 "key1", value 是字符串 "value 1"
[{} , 10086] , // key 是个对象, value 是数值 10086
[ 5, {} ] // key 是个数值类型, value 是对象
];
let map = new Map(array); // 将数组传入 Map 构造函数中
Map 可用的 方法
set(key, value)
: 向其中加入一个键值对get(key)
: 若不存在 key 则返回undefined
has(key)
:返回布尔值delete(key)
: 删除成功则返回 true, 若key不存在或者删除失败会返回 falseclear()
: 将全部元素清除
size 属性, 属性值为 map 中键值对的个数
遍历方法 forEach()
和数组的 forEach 方法类似, 回调函数中都包含3个参数 值, 键, 和 调用这个方法的 Map 集合本身
map.forEach(function(value, key, ownerMap){
console.log(key, value); // 每对键和值
console.log(ownerMap === map); // true
});
Set 集合
Set 和 Map 最大的区别是只有键 key 而没有 value, 所以一般用来判断某个元素(key)是否存在于其中.
创建和初始化方法, 和 Map 大同小异
既可以创建一个空 set 也可以用数组来初始化一个非空的set. 和 Map 不同的是, 数组是一维数组, 每个元素都会成为 set 的键.例如:
// 创建一个数组
let array = [1, 'str']; // 一维数组
// 用数组来初始化 set
let set = new Set(array);
set 的方法
add(key)
: 往set添加一个元素, 如果传入多个参数, 则只会把第一个加入进去
let set = new Set();
set.add(1, 2, 3);
console.log(set.has(1), set.has(2), set.has(3)); // true false false 可以看到只有第一个参数被加入进了 set
has(key)
delete(key)
clear()
遍历方法 forEach
和 Map 的 forEach 方法相似, 回调函数的参数也是3个 (value, key, ownerSet). 按道理来说因为 set 中只有 key 没有 value, 那么会掉函数中不应该存在 value 这个参数, 那么为什么这个 value 参数仍然存在呢?可能是因为 数组和 Map 的 forEach 方法的回调函数的参数都是这三个, 如果对于 Set 而改变了参数, 那么就会丢失了一致性. 这个理由......
那么既然没有 value , 那么这个value的值是什么呢?答案是和key 一样.我们可以把value和key 划等号了.下面这段代码可以验证这个说法.
set.forEach(function(value, key, ownerSet){
console.log(value === key, set === ownerSet); // true true
});
WeakSet 和 WeakMap
这两个集合比之前的两个集合在名字之前都加上了 Weak
, 这个 Weak
可以直译成弱
, 这个弱指的是弱引用, 那么前面不带Weak的 Set 和 Map就不弱, 就是强了, 这个强指的是强引用.
与 Set 和 Map 的区别
- 先说表层的区别:
- 弱版本集合的 key 只能是对象, 对于 value 的类型没有限制.
- 弱版本集合没有 forEach 方法, 也没有 for in 方法, 也不能用数组来初始化(会报错).
- 弱版本可用的方法较少. WeakSet 只有
add, has, delete
方法可用; WeakMap 只有set, has, get, delete
方法可用.
- 根本区别
弱版本的集合和它们对应的强版本根本的区别在对于对象的引用的强弱上, 而对象指的是 key 位置的对象, 即以对象为key的情况.
强弱版本对于 key 是对象时的引用机制如下:
将对象设置为 key 时, 就在集合中保存了这个对象的引用. 当这个对象没有其他引用了的时候, 即只有集合还引用着这个对象的时候, 弱类型的集合会放弃对这个对象的引用, 把这个对象从集合里移除, 不让它继续存在于集合中了, 有些“赶尽杀绝”的意思; 但是强类型的集合还会一直保存着对这个对象的引用, 就把它一直放在集合里.这就是 [WeakSet 和 WeakMap] 与 [Set 和 Map] 的根本区别.
要注意的是这个机制只作用于 key , 而 value 位置绑定的对象无论是否还存在别的引用, WeakMap 都不会放弃这个对象.只有这个位置的 key 绑定的对象没有其他引用时, 才会把 key 和 value 都放弃. 决定权在于 key 位置.
弱版本集合的主要用处
若版本集合可以用在需要生命周期管理的地方,例如保存对一个 DOM 对象的引用, 如果一个 DOM 对象使用完毕, 没有其他的引用了, 那么它应该被 垃圾回收,以免产生内存泄漏,那么弱版本的集合就最适合用来保存这样的对象了。
注意:四种集合都是有序的, 即元素被添加进去的顺序就是在内部保存的顺序. 对于用数组来初始化的集合也一样, 按照在数组中的位置依次添加进集合中.
ES6 中的 Map和Set的更多相关文章
- ES6中的Map集合(与java里类似)
Set类型可以用来处理列表中的值,但是不适用于处理键值对这样的信息结构.ES6也添加了Map集合来解决类似的问题 一.Map集合 JS的对象(Object),本质上是键值对的集合(Hash结构),但是 ...
- ES6中的Map
今天小编和大家一起探讨一下引用类型中的map,在其中会有一些map与数组联合应用,还有和map类似的weakmap类型的说明,这篇文章同时也增加了一些操作数组的办法和实际应用.大家也可以关注我的微信公 ...
- 彻底弄懂ES6中的Map和Set
Map Map对象保存键值对.任何值(对象或者原始值) 都可以作为一个键或一个值.构造函数Map可以接受一个数组作为参数. Map和Object的区别 一个Object 的键只能是字符串或者 Symb ...
- ES6中的Set和Map集合
前面的话 在ES6标准制定以前,由于可选的集合类型有限,数组使用的又是数值型索引,因而经常被用于创建队列和栈.如果需要使用非数值型索引,就会用非数组对象创建所需的数据结构,而这就是Set集合与Map集 ...
- ES6中map数据结构学习
在项目中遇到一个很恶心的需求,然后发现ES6中的map可以解决,所以简单学习了一下map. Javascript的Object本身就是键值对的数据结构,但实际上属性和值构成的是“字符串-值”对,属性只 ...
- ES6 Set 和 Map
ES5 模拟Set 与 Map 集合 Set 常用于检查对象中是否存在某个键名 Map集合常被用于获取已存的信息 所有对象的属性名必须是字符串,那么必须确保每个键名都是字符串类型且在对象中是唯一的 数 ...
- ES6新特性:Javascript中的Map和WeakMap对象
Map对象 Map对象是一种有对应 键/值 对的对象, JS的Object也是 键/值 对的对象 : ES6中Map相对于Object对象有几个区别: 1:Object对象有原型, 也就是说他有默认的 ...
- ES6中的Set、Map数据结构
Map.Set都是ES6新的数据结构,他们都是新的内置构造函数.也就是说typeof的结果,多了两个. 他们是什么: Set是不能重复的数组. Map是可以任何东西当做键的对象: ES6 提供 ...
- ES6中Set 和 Map用法
JS中Set与Map用法 一.Set 1.基本用法 ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个构造函数,用来生成 Set 数据结构. ...
随机推荐
- 个人经验~mysql故障处理思路
一 简介:个人经验总结 二 思路: 从整体上再进行梳理 三 linux角度 1 硬件是否有问题 常见主板 raid卡 和raid磁盘组 2 综合指标 负载 uptime : 1min 5min ...
- 编写灵活、稳定、高质量的 css代码的规范
语法 用两个空格来代替制表符(tab) -- 这是唯一能保证在所有环境下获得一致展现的方法. 为选择器分组时,将单独的选择器单独放在一行. 为了代码的易读性,在每个声明块的左花括号前添加一个空格. 声 ...
- Difference between plt.draw() and plt.show() in matplotlib
Difference between plt.draw() and plt.show() in matplotlib down voteaccepted plt.show() will display ...
- openstack swift节点安装手册1-节点配置
本文参照官方教程:http://docs.openstack.org/project-install-guide/object-storage/draft/environment-networking ...
- 在Asp.Net Core中使用中间件保护非公开文件
在企业开发中,我们经常会遇到由用户上传文件的场景,比如某OA系统中,由用户填写某表单并上传身份证,由身份管理员审查,超级管理员可以查看. 就这样一个场景,用户上传的文件只能有三种人看得见(能够访问) ...
- 003_饿了么chaosmonkey实现
背景 公司目前的服务设计大部分满足 design for failure 理念.随着业务复杂度的提升,我们很难再保证对系统故障的容错性.我们需要工具来验证服务的容错性,基于这个需求我们使用了 tc 工 ...
- centos6.5生产环境编译安装nginx-1.11.3并增加第三方模块ngx_cache_purge、nginx_upstream_check、ngx_devel_kit、lua-nginx
1.安装依赖包 yum install -y gcc gcc-c++ pcre-devel openssl-devel geoip-devel 2.下载需要的安装包 LuaJIT-2.0.4.zip ...
- jdk写webservice
jdk写webservice 1.定义一个需要发布的类,使用@WebService注解. 2.需要发布的方法可以不用@WebMethod注解,如果需要改变访问方法名,可用@WebMethod修改. 3 ...
- Android命令Monkey压力测试,详解
一.Monkey 是什么?Monkey 就是SDK中附带的一个工具. 二.Monkey 测试的目的?:该工具用于进行压力测试. 然后开发人员结合monkey 打印的日志 和系统打印的日志,结局测试中出 ...
- python-找出100以内的质数
质数:就是只能被1和本身整除的数,1除外,如2,3,5,7,11,13等等 ##求一百以内的质数(1和本身除尽的数)if __name__ == '__main__': list=[] flag=Fa ...