Set和Map是ES6中新增的数据结构,Set是集合,无序唯一,Map类似于对象,也是"key-value"形式,但是key不局限于字符串。

1.Set的用法

Set是构造函数,可以使用new初始化一个Set实例,如下所示

var set = new Set();
set.add(2);
set.add(2);
set.add(3);
set.add('hello');
console.log(set,set.size);
//也可以使用数组或类数组作为参数进行初始化
var s1 = new Set([2,3,4,2,3,10]);
console.log(s1,s1.size);
Set [ 2, 3, "hello" ] 3
Set [ 2, 3, 4, 10 ] 4

Set集合具有唯一性,因此不管是向Set中添加重复的元素还是使用数组作为参数,都会自动剔除重复的元素(内部使用的是等值算法),包括NaN,(+0,-0)。因此数组去重的功能可以借助这个特性来做,如下所示

var arr_unique = arr => [...new Set(arr)];//这里使用Array.from方法一样,Array.from(new Set(arr))
console.log(arr_unique([3,3,4,5,6,6,NaN,NaN,+0,-0]));
Array [ 3, 4, 5, 6, NaN, 0 ]

但是两个对象总是不相等,因此它们的内存地址不同。

Set的实例方法和属性

属性有size,constructor,size记录Set实例的元素总数,constructor指向Set构造函数,即Set函数,如下所示

var s = new Set([1,2,3]);
console.log(s.size);
console.log(Object.is(s.constructor,Set));
3
true

方法可以分为两类:操作方法和遍历方法。操作方法有add,delete,has,clear,用法如下所示

var s2 = new Set();
s2.add(1);//add添加元素
s2.add(2);
s2.add('hello');
console.log(s2.size);
s2.delete(2);//delete删除指定元素
console.log(s2.size,s2);
console.log(s2.has(2));//has判断指定元素是否存在
s2.clear();//clear清空所有元素
console.log(s2.size,s2);
3
2 Set [ 1, "hello" ]
false
0 Set [ ]

遍历方法有keys,values,entries,forEach,用法如下所示

var s3 = new Set([2,'hello']);
var keys = s3.keys(),
values = s3.values(),
entries = s3.entries();
//由于Set没有键名,只有键值,故keys和values是一样的效果
for(let x of keys){
console.log(x);
}
for(let x of values){
console.log(x);
}
for(let x of entries){
console.log(x);
}
//Set的默认迭代器就是values,因此可以对Set直接使用for..of遍历
console.log(s3[Symbol.iterator] === s3.values);
for(let x of s3){
console.log(x);
}
2
hello
2
hello
Array [ 2, 2 ]
Array [ "hello", "hello" ]
true
2
hello

2.WeakSet

WeakSet与Set类似,只不过前者只存放对象,且是弱引用。WeakSet实例不可遍历,没有size属性。用法如下

var ws = new WeakSet();
var obj = {};
var foo = {}; ws.add(window);
ws.add(obj); console.log(ws.has(window));
console.log(ws.has(obj)); ws.delete(window);
console.log(ws.has(window)); true
true
false

3.Map

Map类似Object,也是"key-value"的集合,但是Map的键值不限于字符串,如下所示

var map = new Map();
var obj = {};
map.set(obj,"hello");
console.log(map.get(obj));
hello

Map也接收一个数组作为参数,数组的成员将变成Map的成员,数组的元素必须是类似key-valye的形式,如下所示

var arr1 = [2,3,4];
var m1 = new Map(arr1);
TypeError: iterable for Map should have array-like objects
//arr1数组的元素不是key-value形式的,故报错
var arr2 = [['name','xiaoming'],['age',20]];
var m2 = new Map(arr2);
console.log(m2.size);
console.log(m2.get("name"),m2.get("age"));
2
xiaoming 20

对同一个键值进行多次的赋值,较后的赋值会覆盖以前的值,且读取一个不存在的键,会返回undefined,如下所示

var arr2 = [['name','xiaoming'],['age',20]];
var m2 = new Map(arr2);
console.log(m2.size);
console.log(m2.get("name"),m2.get("age"));
m2.set('name','zhangsan');
console.log(m2.get('name'));
console.log(m2.get('dsdsdsds'));
2
xiaoming 20
zhangsan
undefined

如果键值不是基本数据类型,而是引用类型的话,对同一对象的引用才会被认为是同一键值(NaN与NaN,+0与-0被视为相同的键),如下所示

var myMap = new Map();
var o = {};
myMap.set(o,"hello");
console.log(myMap.get(o));
myMap.set({x:1},"world");
console.log(myMap.get({x:1}));
myMap.set(NaN,"NaN");
myMap.get(NaN); hello
undefined
"NaN"

Map实例的属性和方法

属性有size,constructor:size记录Map键值对数量,constructor指向Map

方法也分为两大类:操作方法和遍历方法,操作方法有set,get,has,delete,clear等,用法如下所示

var m = new Map();
m.set('name','lisi');
m.set('age',20);
console.log(m.get('name'));
console.log(m.has('name'));
m.delete('name');
console.log(m.has('name'));
m.clear();
console.log(m.has('age'));
lisi
true
false
false

遍历方法有keys,values,entries,forEach等,用法如下所示

var m = new Map();
m.set('name','lisi');
m.set('age',20);
for(let key of m.keys()){
console.log(key);
}
for(let value of m.values()){
console.log(value);
}
for(let [key,value] of m.entries()){
console.log(key+':'+value);
}
console.log(Map.prototype[Symbol.iterator] === Map.prototype.entries);//Map的默认遍历器是entries
for(let [key,value] of m){
console.log(key+':'+value);
}
m.forEach( (value,key) => console.log(key+':'+value));
name
age
lisi
20
name:lisi
age:20
true
name:lisi
age:20
name:lisi
age:20

利用扩展运算符可以快速将Map转换成数组,因此可以利用数组的特性为Map实例添加一些方法,如map,filter等,如下所示

var m = new Map();
m.set('name','lisi');
m.set('age',20);
Map.prototype.filter = function(operatefun){
return new Map([...this].filter(operatefun));
};
console.log(m.filter(([key,value])=>key!='age')); Map.prototype.map = function(operatefun){
return new Map([...this].map(operatefun));
};
console.log(m.map(([key,value]) =>[key+'_new',value+'_new']));
Map { name: "lisi" }
Map { name_new: "lisi_new", age_new: "20_new" }

4.WeakMap

WeakMap类似于Map,但是只能使用对象作为键值名,其用法如下所示

var weakMap = new WeakMap();
var obj = {x:1};
weakMap.set('name','xiaoming');
TypeError: "name" is not a non-null object
------------------------------------------------------
var weakMap = new WeakMap();
var obj = {x:1};
weakMap.set(obj,'hello');
weakMap.get(obj);
"hello"

WeakMap的更多用法这里就不赘述了,感兴趣的同学可以自行查看相关文档。

ES6 - Note6:Set与Map的更多相关文章

  1. 前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

    一.ES6的Set.Map数据结构 Map.Set都是ES6新的数据结构,都是新的内置构造函数,也就是说typeof的结果,多了两个: Set 是不能重复的数组 Map 是可以任何东西当做键的对象 E ...

  2. es6之set和map

    1.set ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值,set本身就是构造函数,所以可以通过new的方式来创建对象 // 例一 可以做数组去重用 var set ...

  3. 深入理解ES6之—set与map

    Set是无重复值的有序列表.Set会自动移除重复的值,因此你可以使用它来过滤数组中重复的值并返回结果. Map是有序的键值对,其中的键允许是任何类型. Set和Map是es6新增的两个数据集合. Se ...

  4. ES6新增的数据类型Map和Set。

    Javascript的默认对象表示方式 {} ,即一组键值对. 但是Javascript的对象有个小问题,就是键必须是字符串.但实际上Number或者其他数据类型作为键也是非常合理的. 为了解决这个问 ...

  5. ES6中Set 和 Map用法

    JS中Set与Map用法 一.Set 1.基本用法 ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个构造函数,用来生成 Set 数据结构. ...

  6. es6入门set和map

    ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化. var set = new Set([1, ...

  7. ES6,新增数据结构Map的用法

    Javascript的Object本身就是键值对的数据结构,但实际上属性和值构成的是”字符串-值“对,属性只能是字符串,如果传个对象字面量作为属性名,那么会默认把对象转换成字符串,结果这个属性名就变成 ...

  8. ES6学习笔记之map、set与数组、对象的对比

    ES6 ES5中的数据结构,主要是用Array和Object.在ES6中主要新增了Set和Map数据结构.到目前为止,常用的数据结构有四种Array.Object.Set.Map.下面话不多说了,来一 ...

  9. ES6系列_12之map数据结构

    1.map数据结构出现的原因? JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键.这给它的使用带来了很大的限制.为了能实现将对象作为键 ...

随机推荐

  1. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

  2. 将 java 项目打包成可运行的 jar 包(main 函数带参数),并上传到 linux 服务器上运行

    一.概述 java项目有两种架构,一种是 B/S 架构的,一种是 C/S 架构的. 对于 B/S 架构来说,我们常见的 java ee 即是 B/S 架构,通常,开发人员会在本地进行开发,然后将项目打 ...

  3. windows 环境和linux环境下 ping命令的区别:

    Ping 是Windows自带的一个DOS命令.利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障.该命令可以加许多参数使用,键入Ping按回车即可看到详细说明.Ping 命令可 ...

  4. WPF计算

    设计思路: 用WPF窗体设计,在第一个数和第二个数的文本框中输入数值,单击录题按钮,数值保存在n1,n2文档中,把要做的题都保存完后,单击开始按钮,开始做题,每做完一道题,按Enter键,进入下一题, ...

  5. 一步一步学ROP之linux_x64篇

    一步一步学ROP之linux_x64篇 一.序 **ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防 ...

  6. [PHP源码阅读]strlen函数

    文章来自:http://www.hoohack.me/2016/02/22/phps-source-analytics-strlen 我在github有对PHP源码更详细的注解.感兴趣的可以围观一下, ...

  7. 剑指Offer面试题:22.二叉搜索树的后序遍历序列

    一.题目:二叉搜索树的后序遍历序列 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 例如在下面 ...

  8. JavaScript多文件下载

    对于文件的下载,可以说是一个十分常见的话题,前端的很多项目中都会有这样的需求,比如 highChart 统计图的导出,在线图片编辑中的图片保存,在线代码编辑的代码导出等等.而很多时候,我们只给了一个链 ...

  9. SQL Server 事务隔离级别详解

    标签: SQL SEERVER/MSSQL SERVER/SQL/事务隔离级别选项/设置数据库事务级别 SQL 事务隔离级别 概述 隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一 ...

  10. EF:Fluent API 把一对多映射为一对一

    假设有两张表:A表和B表.A表与B表在数据库中的关系是一对多,但我们需要在EF中映射为一对一. 首先在A实体类和B实体类中互相为对方增加一个实体类的属性: public A { public B B ...