Map 對象保存鍵值對。任何值(對象或者原始值) 都可以作為一個鍵或一個值。 語法 參數 描述 一個Map對象以插入順序迭代其元素 — 一個 for...of 迴圈為每次迭代返回一個[key,value]數組。 鍵的相等(Key equality) 鍵的比較是基於 "SameValueZero" 算 ...
Map
對象保存鍵值對。任何值(對象或者原始值) 都可以作為一個鍵或一個值。
語法
new Map([iterable])
參數
iterable
- Iterable 可以是一個數組或者其他 iterable 對象,其元素或為鍵值對,或為兩個元素的數組。 每個鍵值對都會添加到新的 Map。
null
會被當做undefined。
描述
一個Map對象以插入順序迭代其元素 — 一個 for...of
迴圈為每次迭代返回一個[key,value]數組。
鍵的相等(Key equality)
鍵的比較是基於 "SameValueZero" 演算法:NaN
是與 NaN
相同的(雖然 NaN !== NaN
),剩下所有其它的值是根據 === 運算符的結果判斷是否相等。在目前的ECMAScript規範中,-0
和+0
被認為是相等的,儘管這在早期的草案中並不是這樣。有關詳細信息,請參閱瀏覽器相容性 表中的“value equality for -0 and 0”。
Objects 和 maps 的比較
Object
和 Map
類似的是,它們都允許你按鍵存取一個值、刪除鍵、檢測一個鍵是否綁定了值。因此(並且也沒有其他內建的替代方式了)過去我們一直都把對象當成 Map
使用。不過Map
和 Object
有一些重要的區別,在下列情況里 Map
會是更好的選擇:
- 一個對象的鍵只能是
字元串
或者Symbols
,但一個Map
的鍵可以是任意值,包括函數、對象、基本類型。 - 你可以通過
size
屬性直接獲取一個Map
的鍵值對個數,而Object
的鍵值對個數只能手動計算。 Map
是可迭代的,而Object
的迭代需要先獲取它的鍵數組然後再進行迭代。Object
都有自己的原型,所以原型鏈上的鍵名有可能和對象上的鍵名產生衝突。雖然 ES5 開始可以用map = Object.create(null)
來創建一個沒有原型的對象,但是這種用法不太常見。- Map 在涉及頻繁增刪鍵值對的場景下會有些性能優勢。
屬性
Map.length
- 屬性 length 的值為 0 。
get Map[@@species]
- 本構造函數用於創建派生對象。
Map.prototype
- 表示
Map
構造器的原型。 允許添加屬性從而應用於所有的Map
對象。
Map
實例
所有的 Map
對象實例都會繼承 Map.prototype
。
屬性
Map.prototype.constructor
- 返回一個函數,它創建了實例的原型。預設是
Map
函數。 Map.prototype.size
- 返回Map對象的鍵/值對的數量。
方法
Map.prototype.clear()
- 移除Map對象的所有鍵/值對 。
Map.prototype.delete(key)
- 移除任何與鍵相關聯的值,並且返回該值,該值在之前會被Map.prototype.has(key)返回為true。之後再調用Map.prototype.has(key)會返回false。
Map.prototype.entries()
- 返回一個新的
Iterator
對象,它按插入順序包含了Map對象中每個元素的[key, value]
數組
。 Map.prototype.forEach(callbackFn[, thisArg])
- 按插入順序,為
Map
對象里的每一鍵值對調用一次callbackFn函數。如果為forEach提供了thisArg,它將在每次回調中作為this值。 Map.prototype.get(key)
- 返回鍵對應的值,如果不存在,則返回undefined。
Map.prototype.has(key)
- 返回一個布爾值,表示Map實例是否包含鍵對應的值。
Map.prototype.keys()
- 返回一個新的
Iterator
對象, 它按插入順序包含了Map對象中每個元素的鍵 。 Map.prototype.set(key, value)
- 設置Map對象中鍵的值。返回該Map對象。
Map.prototype.values()
- 返回一個新的
Iterator
對象,它按插入順序包含了Map對象中每個元素的值 。 Map.prototype[@@iterator]()
- 返回一個新的
Iterator
對象,它按插入順序包含了Map對象中每個元素的[key, value]
數組
。
示例
使用映射對象
1 var myMap = new Map(); 2 3 var keyObj = {}, 4 keyFunc = function () {}, 5 keyString = "a string"; 6 7 // 添加鍵 8 myMap.set(keyString, "和鍵'a string'關聯的值"); 9 myMap.set(keyObj, "和鍵keyObj關聯的值"); 10 myMap.set(keyFunc, "和鍵keyFunc關聯的值"); 11 12 myMap.size; // 3 13 14 // 讀取值 15 myMap.get(keyString); // "和鍵'a string'關聯的值" 16 myMap.get(keyObj); // "和鍵keyObj關聯的值" 17 myMap.get(keyFunc); // "和鍵keyFunc關聯的值" 18 19 myMap.get("a string"); // "和鍵'a string'關聯的值" 20 // 因為keyString === 'a string' 21 myMap.get({}); // undefined, 因為keyObj !== {} 22 myMap.get(function() {}) // undefined, 因為keyFunc !== function () {}
將NaN作為映射的鍵
NaN
也可以作為Map對象的鍵. 雖然 NaN
和任何值甚至和自己都不相等(NaN !== NaN
返回true), 但下麵的例子表明, 兩個NaN
作為Map的鍵來說是沒有區別的:
1 var myMap = new Map(); 2 myMap.set(NaN, "not a number"); 3 4 myMap.get(NaN); // "not a number" 5 6 var otherNaN = Number("foo"); 7 myMap.get(otherNaN); // "not a number"
使用for..of
方法迭代映射
映射也可以使用for..of迴圈來實現迭代:
1 var myMap = new Map(); 2 myMap.set(0, "zero"); 3 myMap.set(1, "one"); 4 for (var [key, value] of myMap) { 5 console.log(key + " = " + value); 6 } 7 // 將會顯示兩個log。一個是"0 = zero"另一個是"1 = one" 8 9 for (var key of myMap.keys()) { 10 console.log(key); 11 } 12 // 將會顯示兩個log。 一個是 "0" 另一個是 "1" 13 14 for (var value of myMap.values()) { 15 console.log(value); 16 } 17 // 將會顯示兩個log。 一個是 "zero" 另一個是 "one" 18 19 for (var [key, value] of myMap.entries()) { 20 console.log(key + " = " + value); 21 } 22 // 將會顯示兩個log。 一個是 "0 = zero" 另一個是 "1 = one"
使用forEach()
方法迭代映射
映射也可以通過forEach()方法迭代:
1 myMap.forEach(function(value, key) { 2 console.log(key + " = " + value); 3 }, myMap) 4 // 將會顯示兩個logs。 一個是 "0 = zero" 另一個是 "1 = one"
映射與數組對象的關係
1 var kvArray = [["key1", "value1"], ["key2", "value2"]]; 2 3 // 使用映射對象常規的構造函數將一個二維鍵值對數組對象轉換成一個映射關係 4 var myMap = new Map(kvArray); 5 6 myMap.get("key1"); // 返回值為 "value1" 7 8 // 使用展開運算符將一個映射關係轉換成一個二維鍵值對數組對象 9 console.log(uneval([...myMap])); // 將會向您顯示和kvArray相同的數組 10 11 // 或者使用展開運算符作用在鍵或者值的迭代器上,進而得到只含有鍵或者值得數組 12 console.log(uneval([...myMap.keys()])); // 輸出 ["key1", "key2"]