细说es6中的Set和Map

1.Set

ES6 提供了新的数据结构 Set。它相似于数组,可是成员的值都是惟一的,没有重复的值。
Set 自己是一个构造函数,用来生成 Set 数据结构。
基本用法:
const set = new Set();
set函数能够接受一个数组(或者具备iterable 接口的其余数据结构)做为参数,用来初始化:
const set = new Set(['1','2','3','2']); //注意:set结构不会接受重复的参数,这也体现了set结构去重的方法数组

扩展运算符: ... //能够把set数据结构转化为数组类型
例如:
[...set]
另外一种方法是利用Array.from()方法:
const set = new Set(['1','2','3']);
例如: Array.from(set)
在set结构中,两个对象老是不相等的,NaN也等于其自己。数据结构

下面是set结构的属性和方法:
Set 结构的实例有如下属性:
Set.prototype.constructor:构造函数,默认就是Set函数。
Set.prototype.size:返回Set实例的成员总数。函数

Set 实例的方法分为两大类:操做方法(用于操做数据)和遍历方法(用于遍历成员)。下面先介绍四个操做方法。
add(value):添加某个值,返回 Set 结构自己。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除全部成员,没有返回值。
例如:
set.add(10) //向set添加一个成员
set.delete(10) //删除set一个成员
set.has(10) //检测这个值是否存在,返回布尔值true或false
set.clear() //清除全部set成员,没有返回值prototype

遍历操做
Set 结构的实例有四个遍历方法,能够用于遍历成员。设计

keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每一个成员
须要特别指出的是,Set的遍历顺序就是插入顺序。这个特性有时很是有用,好比使用 Set 保存一个回调函数列表,调用时就能保证按照添加顺序调用。orm

(1)keys(),values(),entries()
keys方法、values方法、entries方法返回的都是遍历器对象(详见《Iterator 对象》一章)。因为 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),因此keys方法和values方法的行为彻底一致。对象

2.WeakSet

含义:
WeakSet 结构与 Set 相似,也是不重复的值的集合。可是,它与 Set 有两个区别。
(1),WeakSet 的成员只能是对象,而不能是其余类型的值。
WeakSet 适合临时存放一组对象
WeakSet 的成员是不适合引用的,由于它会随时消失。另外,因为 WeakSet 内部有多少个成员,取决于垃圾回收机制有没有运行,运行先后极可能成员个数是不同的,而垃圾回收机制什么时候运行是不可预测的,所以 ES6 规定 WeakSet 不可遍历。
做为构造函数,WeakSet 能够接受一个数组或相似数组的对象做为参数。(实际上,任何具备 Iterable 接口的对象,均可以做为 WeakSet 的参数。)该数组的全部成员,都会自动成为 WeakSet 实例对象的成员。
注意,是a数组的成员成为 WeakSet 的成员,而不是a数组自己。这意味着,数组的成员只能是对象。接口

WeakSet 结构有如下三个方法。
WeakSet.prototype.add(value):向 WeakSet 实例添加一个新成员。
WeakSet.prototype.delete(value):清除 WeakSet 实例的指定成员。
WeakSet.prototype.has(value):返回一个布尔值,表示某个值是否在 WeakSet 实例之中。ip

const ws = new WeakSet();
const obj = {};
const foo = {};内存

ws.add(window);
ws.add(obj);

ws.has(window); // true
ws.has(foo); // false

ws.delete(window);
ws.has(window); // false

另外:WeakSet 没有size属性,没有办法遍历它的成员。

3.Map

含义和基本用法
JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),可是传统上只能用字符串看成键。这给它的使用带来了很大的限制。
为了解决这个问题,ES6 提供了 Map 数据结构。它相似于对象,也是键值对的集合,可是“键”的范围不限于字符串,各类类型的值(包括对象)均可以看成键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。若是你须要“键值对”的数据结构,Map 比 Object 更合适。
例如:
const m = new Map();
const o = {p: 'Hello World'};

m.set(o, 'content')
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false
事实上,不只仅是数组,任何具备 Iterator 接口、且每一个成员都是一个双元素的数组的数据结构(详见《Iterator》一章)均可以看成Map构造函数的参数。这就是说,Set和Map均可以用来生成新的 Map。

实例的属性和操做方法

(1)size 属性

size属性返回 Map 结构的成员总数。

const map = new Map();
map.set('foo', true);
map.set('bar', false);

map.size // 2
(2)set(key, value)

set方法设置键名key对应的键值为value,而后返回整个 Map 结构。若是key已经有值,则键值会被更新,不然就新生成该键。

const m = new Map();

m.set('edition', 6) // 键是字符串
m.set(262, 'standard') // 键是数值
m.set(undefined, 'nah') // 键是 undefined
set方法返回的是当前的Map对象,所以能够采用链式写法。

let map = new Map()
.set(1, 'a')
.set(2, 'b')
.set(3, 'c');
(3)get(key)

get方法读取key对应的键值,若是找不到key,返回undefined。

const m = new Map();

const hello = function() {console.log('hello');};
m.set(hello, 'Hello ES6!') // 键是函数

m.get(hello) // Hello ES6!
(4)has(key)

has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。

const m = new Map();

m.set('edition', 6);
m.set(262, 'standard');
m.set(undefined, 'nah');

m.has('edition') // true
m.has('years') // false
m.has(262) // true
m.has(undefined) // true
(5)delete(key)

delete方法删除某个键,返回true。若是删除失败,返回false。

const m = new Map();
m.set(undefined, 'nah');
m.has(undefined) // true

m.delete(undefined)
m.has(undefined) // false
(6)clear()

clear方法清除全部成员,没有返回值。

let map = new Map();
map.set('foo', true);
map.set('bar', false);

map.size // 2
map.clear()
map.size // 0

遍历方法

Map 结构原生提供三个遍历器生成函数和一个遍历方法。

keys():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回全部成员的遍历器。
forEach():遍历 Map 的全部成员。
须要特别注意的是,Map 的遍历顺序就是插入顺序。

4.WeakMap

WeakMap结构与Map结构相似,也是用于生成键值对的集合。
WeakMap与Map的区别有两点。

首先,WeakMap只接受对象做为键名(null除外),不接受其余类型的值做为键名。
其次,WeakMap的键名所指向的对象,不计入垃圾回收机制。

WeakMap的设计目的在于,有时咱们想在某个对象上面存放一些数据,可是这会造成对于这个对象的引用。请看下面的例子。

const e1 = document.getElementById('foo');
const e2 = document.getElementById('bar');
const arr = [
[e1, 'foo 元素'],
[e2, 'bar 元素'],
];
基本上,若是你要往对象上添加数据,又不想干扰垃圾回收机制,就可使用 WeakMap。一个典型应用场景是,在网页的 DOM 元素上添加数据,就可使用WeakMap结构。当该 DOM 元素被清除,其所对应的WeakMap记录就会自动被移除。

const wm = new WeakMap();

const element = document.getElementById('example');

wm.set(element, 'some information');wm.get(element) // "some information"上面代码中,先新建一个 Weakmap 实例。而后,将一个 DOM 节点做为键名存入该实例,并将一些附加信息做为键值,一块儿存放在 WeakMap 里面。这时,WeakMap 里面对element的引用就是弱引用,不会被计入垃圾回收机制。总之,WeakMap的专用场合就是,它的键所对应的对象,可能会在未来消失。WeakMap结构有助于防止内存泄漏。

相关文章
相关标签/搜索