### Set
ES6提供了新的数据结构:`Set`,它类似于数组,但成员的值都是唯一的,没有重复。`Set`本身是一个构造函数,用来生成`Set`数据结构
```js
const s = new Set()
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x))
for (let i of s) {
console.log(i)
}
// 2 3 5 4
```
`Set`函数接受一个数组,或者其他具有`iterable`接口的数据结构,作为参数,用来初始化
```js
const set = new Set([1, 2, 3, 4, 4])
[...set]
// [1, 2, 3, 4]
```
利用`Set`我们可以很方便的对数组进行去重操作
```js
[...new Set([1, 2, 2, 3])]
```
在`Set`内部,两个`NaN`总是相等的,而两个对象总是不相等的。
#### Set实例的属性和方法
`Set`实例有以下属性:
- `Set.prototype.constructor`:构造函数,默认就是 `Set` 函数
- `Set.prototype.size`:返回`Set`实例的成员总数
`Set`实例的方法分为操作数据方法和遍历方法
##### 操作数据方法
- `add(value)`:添加某个值,返回`Set`结构本身
- `delete(value)`:删除某个值,返回布尔值,表示是否删除成功
- `has(value)`:返回布尔值,表示参数是否为`Set`成员
- `clear()`:清除所有成员,没有返回值
```js
let s = new Set()
s.add(1).add(2).add(2)
s.size // 2
s.has(1) // true
s.has(2) // true
s.has(3) // false
s.delete(2)
s.has(2) // false
```
##### 遍历方法
`Set`有4个遍历数据的方法:
- `keys()`:返回键名的遍历器
- `values()`:返回键值的遍历器
- `entries()`:返回键值对的遍历器
- `forEach()`:使用回调函数遍历每个成员
```js
let set = new Set(['red', 'green', 'blue'])
for (let item of set.keys()) {
console.log(item)
}
// red
// green
// blue
for (let item of set.values()) {
console.log(item)
}
// red
// green
// blue
for (let item of set.entries()) {
console.log(item)
}
// ['red', 'red']
// ['green', 'green']
// ['blue', 'blue']
```
### WeakSet
`WeakSet`结构与`Set`类似,也是不重复的值得集合,它与`Set`有两点不同:
- `WeakSet`的成员只能是对象,而不能是其他类型的值
- `WeakSet`中的对象都是弱引用,即垃圾回收机制不考虑`WeakSet`对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象是否还存在于`WeakSet`之中。
`WeakSet`是一个构造函数,可以使用`new`命令创建。
```js
const ws = new WeakSet()
```
`WeakSet`可以接受一个数组或类似数组的对象作为参数。
```js
const a = [[1, 2], [3, 4]]
const ws = new WeakSet(a)
// WeakSet { [1, 2], [3, 4] }
```
`WeakSet`有以下3个方法:
- `WeakSet.prototpye.add(value)`:向`WeakSet`实例添加一个新成员
- `WeakSet.prototype.delete(value)`:清除`WeakSet`实例的指定成员
- `WeakSet.prototype.has(value)`:返回一个布尔值,表示某个值是否在`WeakSet`实例中。
### Map
ES6提供了`Map`数据结构,它类似于对象,也是键值对的集合,但键的范围不限于字符串,各种类型的值(包括对象)都可以当做键。它是一种更完善的Hash结构的表现。
```js
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
```
#### Map实例的属性和方法
##### size属性
`size`属性返回`Map`结构的成员总数
```js
const map = new Map()
map.set('foo', true)
map.set('bar', false)
map.size // 2
```
##### set(key, value)
`set`方法设置`key`所对应的键值,然后返回整个`Map`结构
```js
const m = new Map()
m.set('edition', 6) // 键是字符串
m.set(262, 'standard') // 键是数值
m.set(undefined, 'nah') // 键是undefined
```
##### get(key)
`get`方法读取`key`对应的键值,如果找不到则返回undefined
```js
const m = new Map()
const hello = function () { console.log('hello') }
m.set(hello, 'Hello ES6') // 键是函数
m.get(hello)
// Hello ES6
```
##### has(key)
`has`方法返回一个布尔值,表示某个键是否在`Map`结构中
```js
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
```
##### delete(key)
`delete`方法删除某个键,返回`true`,如果失败返回`false`
```js
const m = new Map()
m.set(undefined, 'nah')
m.has(undefined) // true
m.delete(undefined)
m.has(undefined) // false
```
##### clear()
`clear`方法清除所有成员,没有返回值
```js
let map = new Map()
map.set('foo', true)
map.set('bar', false)
map.size // 2
map.clear()
map.size // 0
```
#### 遍历方法
`Map`原生提供了3个遍历器生成函数和1个遍历方法
- `keys()`:返回键名的遍历器
- `values()`:返回键值的遍历器
- `entries()`:返回所有成员的遍历器
- `forEach()`:遍历`Map`的所有成员
### WeakMap
`WeakMap`结构与`Map`结构类似,也用于生成键值对的集合
```js
const wm1 = new WeakMap()
const key = { foo: 1 }
wm1.set(key, 2)
wm1.get(key) // 2
```
`WeakMap`与`Map`的区别在于,`WeakMap`只接受对象作为键名(`null`除外),另外`WeakMap`的键名所指向的对象不计入垃圾回收机制