JavaScript 中比Object更強大的Map

 

​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

瀏覽器兼容性

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章