Map對象保存鍵值對,並且能夠記住鍵的原始插入順序,最爲主要的一點是可以以任意值作爲鍵。
語法
new Map([iterable])
iterable:可以是一個數組或者其他iterable對象,其元素爲鍵值對(如:[[1: 'a'],[2: 'b']])。每個鍵值對都會被添加到Map中。當爲null時會被當做undefined。
let map = new Map([[ 1, 'one' ],[ 2, 'two' ]])
//map {1 => "one", 2 => "two"}
鍵是否相等
鍵的比較是基於 sameValueZero算法
NaN是與NaN相等的(雖然NaN !== NaN),其他的值根據 === 運算符的結果進行判斷是否相等
在目前的ECMAScript規範中,-0與+0被認爲是相等的。
Objects 和 maps 的比較
相同點:都允許按鍵存取一個值、刪除鍵、檢測一個鍵是否綁定了值。
區別:
-
Object的鍵只能是字符串或者Symbols,但是Map可以是任意值,包括函數、對象、基本類型。
-
Map中的鍵值是有序的,他會按照我們插入的順序返回,而Object中是無序的。
-
可通過Map.size屬性返回鍵值對的個數,而Object的個數只能手動計算。
-
Map可直接進行迭代,而Object的迭代需要先獲取它的鍵值組。
-
Object有自己的原型,自己設置的鍵名可能會與原型鏈上的鍵名產生衝突。ES5開始可以使用map = Object.create(null)來創建一個沒有原型的對象。
-
Map在涉及頻繁增刪鍵值對的場景下性能更佳。
屬性
Map.length
值爲0,可通過Map.size()計算一個Map中的鍵值對數量
Map.prototype
表示Map構造器的原型。允許添加屬性從而應用於所有的Map對象。
Map實例
所有的Map對象都會繼承Map.prototype。
屬性
Map.prototype.size
返回Map對象的鍵/值對的數量。
Map.prototype.constructor
回一個函數,它創建了實例的原型。默認是Map
函數。
方法
Map.prototype.clear()
移除Map對象的所有鍵/值對 。
Map.prototype.delete(key)
如果 Map
對象中存在該元素,則移除它並返回 true
;否則如果該元素不存在則返回 false
。隨後調用 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]
數組
。
示例
使用Map 對象
let myMap = new Map();
let keyObj = {};
let keyFunc = function() {};
let keyString = 'a string';
// 添加鍵
myMap.set(keyString, "和鍵'a string'關聯的值");
myMap.set(keyObj, "和鍵keyObj關聯的值");
myMap.set(keyFunc, "和鍵keyFunc關聯的值");
myMap.size; // 3
// 讀取值
myMap.get(keyString); // "和鍵'a string'關聯的值"
myMap.get(keyObj); // "和鍵keyObj關聯的值"
myMap.get(keyFunc); // "和鍵keyFunc關聯的值"
myMap.get('a string'); // "和鍵'a string'關聯的值"
// 因爲keyString === 'a string'
myMap.get({}); // undefined, 因爲keyObj !== {}
myMap.get(function() {}); // undefined, 因爲keyFunc !== function () {}
let myMap = new Map();
myMap.set(NaN, "not a number");
myMap.get(NaN); // "not a number"
拓展
複製或合併Maps
這是一個淺複製過程,數據本身並沒有被克隆。
let original = new Map([
[1, 'one']
]);
let clone = new Map(original);
console.log(clone.get(1)); // one
console.log(original === clone); // false.
合併兩個Map對象時,如果有重複的鍵值,則後面的會覆蓋前面的。
拓展運算符的本質是將Map轉爲數組。
let first = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
let second = new Map([
[1, 'uno'],
[2, 'dos']
]);
let merged = new Map([...first, ...second]);
console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
Map對象同數組進行合併時,如果有重複的鍵值,則後面的會覆蓋前面的。
let first = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
let second = new Map([
[1, 'uno'],
[2, 'dos']
]);
let merged = new Map([...first, ...second, [1, 'eins']]);
console.log(merged.get(1)); // eins
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
瀏覽器兼容性