### 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`的鍵名所指向的對象不計入垃圾回收機制