[TOC]
* * * * *
>[info] `Map` 對象保存鍵值對。任何值(對象或者原始值) 都可以作為一個鍵或一個值。
### 一. `Map` 和 普通對象
>[info] `Object` 和 `Map` 類似的一點是,它們都允許你按鍵存取一個值,都可以刪除鍵,還可以檢測一個鍵是否綁定了值。因此,一直以來,我們都把對象當成Map來使用。
現在有了 `Map` ,下面的區別解釋了為什么使用 `Map` 更好點.
~~~
a. 一個對象通常都有自己的原型,所以一個對象總有一個 'prototype' 鍵。不過,從 ES5 開始可以使用 map = Object.create(null) 來創建一個沒有原型的對象。
b. 一個對象的鍵只能是字符串或者 Symbols,但一個 Map 的鍵可以是任意值。
c. 你可以通過 size 屬性很容易地得到一個 Map 的鍵值對個數,而對象的鍵值對個數只能手動確認。
~~~
>[info] 但是這并不意味著你可以隨意使用 `Map`,對象仍舊是最常用的。
`Map` 實例只適合用于集合 `(collections)`,你應當考慮修改你原來的代碼——先前使用對象來處理集合的地方。對象應該用其字段和方法來作為記錄的。
進一步確認是需要用什么:
~~~
a. 在運行之前 key 是否是未知的,是否需要動態地查詢 key 呢?
b. 是否所有的值都是統一類型,這些值可以互換么?
c. 是否需要不是字符串類型的 key ?
d. 鍵值對經常增加或者刪除么?
e. 是否有任意個且非常容易改變的鍵值對?
f. 這個集合可以遍歷么 (Is the collection iterated) ?
~~~
假如以上全是“是”的話,那么你需要用 Map 來保存這個集。
相反,你有固定數目的鍵值對,獨立操作它們,區分它們的用法,那么你需要的是對象。
* * * * *
### 二. 語法
#### 1. 構造 `Map` 對象
~~~
<1>. 使用字面量構造,代碼量少
var f1=function() {},
o1={},
s1=Symbol('rc');
var m1=new Map([
[1,'number'],
['name','wdd'],
[f1,'a function.'],
[o1,'a object'],
[s1,'a Symbol']
]);
<2>. 調用方法,一個一個插入
var m2=new Map();
m2.set(key, value);
~~~
#### 4. `Map.prototype.size`
返回Map對象的鍵/值對的數量。

#### 5. `Map.prototype.clear()`
移除Map對象的所有鍵/值對 。

#### 6. `Map.prototype.delete(key)`
~~~
移除任何與鍵相關聯的值,并且返回該值,該值在之前會被
Map.prototype.has(key) 返回為 true 。之后再調用
Map.prototype.has(key) 會返回 false 。
~~~

#### 7. `Map.prototype.entries()`
返回一個新的 `Iterator` 對象,它按插入順序包含了 `Map` 對象中每個元素的 `[key, value]` 數組。
#### 8. `Map.prototype.forEach(callbackFn[, thisArg])`
~~~
按插入順序,為 Map 對象里的每一鍵值對調用一次 callbackFn 函數。
如果為 forEach 提供了 thisArg,它將在每次回調中作為 this 值。
~~~
#### 9. `Map.prototype.get(key)`
返回鍵對應的值,如果不存在,則返回 `undefined` 。
#### 10. `Map.prototype.has(key)`
返回一個布爾值,表示Map實例是否包含鍵對應的值。

#### 11. `Map.prototype.keys()`
返回一個新的 `Iterator` 對象, 它按插入順序包含了 `Map` 對象中每個元素的鍵 。
#### 12. `Map.prototype.set(key, value)`
設置 `Map` 對象中鍵的值。返回該 `Map` 對象。
#### 13. `Map.prototype.values()`
返回一個新的 `Iterator` 對象,它按插入順序包含了 `Map` 對象中每個元素的值 。
#### 14. `Map.prototype[@@iterator]()`
返回一個新的 `Iterator` 對象,它按插入順序包含了 `Map` 對象中每個元素的 `[key, value]` 數組。
#### 15. 鍵值為 `NaN`
~~~
map中的鍵值如果為 NaN ,那么只要一個值為 NaN ,就可以取出對應的值
(按標準,任何兩個NaN都是不相等的);對于其他的鍵,一律以 === 規則來判斷。
~~~

~~~
var m2 = new Map();
m2.set(NaN, "not a number");
m2.get(NaN); // "not a number"
var otherNaN = Number("foo");
m2.get(otherNaN); // "not a number"
~~~
### 三. 遍歷 `Map`
#### 1. `of` 操作符
可見每一個元素都是一個含有兩個值得數組,就和用字面量組裝時候的一樣。

#### 2. 只遍歷鍵或值


#### 3. `forEach` 方法

>[danger] PS:`Map.keys(), Map.values(), Map.entries()` 這三個在 IE 11 中沒有實現,其他瀏覽器沒問題