天天看點

Map對象和普通對象的7個差別

Map對象和普通對象的7個差別

在 JavaScript 中,普通對象和 ES6 的新對象 Map 都可以存儲鍵值對,但是,它們之間有什麼差別呢?本文将為您一一揭曉。

1、初始化與使用

普通對象可以直接使用字面量進行初始化,而 Map 需要 Map() 構造函數進行初始化,如果想要有初始值,則需要傳遞一個數組或其他元素為鍵值對的可疊代對象。這些鍵值對中的每一個都将被添加到一個新的 Map 中。

const obj = {
  name: 1,
  age: 2,
};
const map = new Map([
  ['name', 1],
  ['age', 2],
]);      

與普通對象相比,Map 作為哈希表提供了許多有用的功能。比如判斷一個key是否在hash表中,在map中可以使用has方法輕松判斷,但是在普通對象中可能會增加複雜度。

另外,set方法可以為Map設定key值,get方法可以擷取value,size屬性可以傳回目前Map中key/value對的數量,而plain對象需要手動計算使用 自己的方法等。詳情見MDN。

2、 密鑰類型

普通對象隻接受字元串和符号作為鍵值,其他類型将被強制轉換為字元串類型,而 Map 可以接受任何類型的鍵值(包括函數、對象或任何原語)。

const obj = {};
const map = new Map();
const key = function () {};
obj[key] = 1;
map.set(key, 1);
// { 'function () {}': 1 }
console.log('obj: ', obj);
// Map(1) { [Function: key] => 1 }
console.log('map: ', map);      

3、Accidental keys

普通對象從原型繼承了許多屬性鍵,例如構造函數等。是以,自己的密鑰很可能與原型上的密鑰發生沖突。但是 Map 預設不包含任何鍵,它隻包含那些顯式放入的。

const obj = {};
const map = new Map();
console.log(obj.constructor); // ƒ Object() { [native code] }
console.log(map.get('constructor')); // undefined      

4、Key order

雖然現在對普通對象的鍵進行了排序,但情況并非總是如此,而且排序很複雜。例如,如果對象中有鍵需要轉換為字元串,則不保留對象鍵的原始順序。雖然 Map 以簡單的方式排序,但它始終與我們插入的順序相同。

const obj = {
  name: 1,
  age: 2,
  3: 4,
};
const map = new Map([
  ['name', 1],
  ['age', 2],
  [3, 4],
]);
// The original order is not preserved.
// {3: 4, name: 1, age: 2}
console.log('obj: ', obj);
// Map(3) { 'name' => 1, 'age' => 2, 3 => 4 }
console.log('map: ', map);      

5、疊代

我們可以使用 for...of 語句或 Map.prototype.forEach 直接疊代 Map 的屬性,而普通對象不能直接疊代。

const obj = {
  name: 1,
  age: 2,
};
const map = new Map([
  ['name', 1],
  ['age', 2],
]);
for (const [key, value] of map) {
  console.log(`${key}: `, value); // name: 1, age: 2
}
map.forEach((value, key) => {
  console.log(`${key}: `, value); // name: 1, age: 2
});
// Plain objects are not iterable directly.
// But we can use functions like `Object.keys` to help us.
Object.keys(obj).forEach((key) => {
  console.log(`${key}: `, obj[key]); // name: 1, age: 2
});      

6、序列化和解析

普通對象支援 JSON 序列化,但 Map 預設無法擷取正确資料。

const obj = {
  name: 1,
  age: 2,
};
const map = new Map([
  ['name', 1],
  ['age', 2],
]);
console.log(JSON.stringify(obj)); // "{"name":1,"age":2}"
console.log(JSON.stringify(map)); // "{}"      

7、性能

Map 對象在涉及頻繁添加和删除鍵值對的場景中表現更好,而普通對象沒有優化。

總結

那麼普通對象應該被 Map 對象替換嗎?

不,如果我們想在 JSON 和原始資料之間轉換或包含特定的業務邏輯,那麼我們應該使用普通對象。因為當我們隻想存儲鍵值對和循環操作或不斷添加和删除屬性時,使用 Map 對象是更好的選擇。

Map對象雖然也是繼承自底層的Object.prototype,但它為我們提供了很多實用的方法來減輕我們的認知負擔,比普通對象更進階。

學習更多技能

請點選下方公衆号