JavaScript中Map和Object的區(qū)別詳解
一、構(gòu)造方式不同
在js中創(chuàng)建object最簡單的方法是通過字面量
(對象/對象映射)
const smbObj = {
1: 'ShowMeBug',
2: 'ShowMeMoney'
};
Map則是通過內(nèi)置構(gòu)造函數(shù)Map創(chuàng)建
(映射)
const smbMap = new Map([ [1, 'ShowMeBug'], [2, 'ShowMeMoney'] ]);
二、對象中的鍵是字符串,映射中的鍵可以是任意類型
- object是鍵值對的集合,但鍵只能是字符串。
- 比如,如果用數(shù)字作 Object 的鍵,則該數(shù)字將轉(zhuǎn)換為字符串
- 而Map的鍵可以是任意類型
- 無論是對象還是映射,鍵都是唯一的。對象中不能有兩個(gè)相同鍵的屬性,映射中也不能有兩個(gè)相同鍵的條目。
在Object中:
//因?yàn)殒I已經(jīng)被轉(zhuǎn)換成字符串,所以無論是獲取數(shù)字1還是字符串'1'的值時(shí),得到的結(jié)果都一樣 console.log(smbObj[1]); //'ShowMeBug' console.log(smbObj['1']); //'ShowMeBug'
在Map中:
//Map 的鍵可以為任意類型,數(shù)字 1 的鍵和字符串 '1' 的鍵并不一樣 console.log(smbMap[1]); //'ShowMeBug' console.log(smbMap['1']); //undefined
三、對象會從原型中繼承多余的鍵
- 使用字面量創(chuàng)建的 Object 會繼承一組來自 Object.prototype 的鍵值對
1.繼承Object.prototype鍵值對
//打印 Object.prototype, //你會發(fā)現(xiàn)它還有 //hasOwnProperty、 //isPrototypeOf、 //toLocaleString、 //toString 等屬性 console.log(Object.prototype);

2.創(chuàng)建{},會繼承Object.prototype
- 當(dāng)你創(chuàng)建一個(gè)普通對象 {} 時(shí),它會自動繼承自 Object.prototype
- 因此,即使你的對象 {} 看起來是“空”的,它也能訪問到這些繼承來的方法。當(dāng)你訪問 socalledEmptyObject[‘toString’] 時(shí),JavaScript 引擎首先在對象自身上查找 toString 屬性,沒找到,然后沿著原型鏈向上查找,在 Object.prototype 上找到了它,所以返回了該函數(shù)。
const socalledEmptyObject = {};
console.log(socalledEmptyObject['toString']);
//? toString() { [native code] }
3.創(chuàng)建對象映射最好用Object.create(null) 來做
//Object.create(null) 能構(gòu)建出沒有原型的對象 const emptyObject = Object.create(null); console.log(emptyObject['toString']); //undefined
四、Map 會保留鍵的順序,對象不會
1.Object
創(chuàng)建對象時(shí),鍵 2 出現(xiàn)在鍵 1 之前。
但在檢索所有鍵時(shí),2 在 1 后面
const smbObj = {
2: 'ShowMeMoney',
1: 'ShowMeBug'
};
const keys = Object.keys(smbObj);
console.log(keys);
//["1", "2"]
const keyValuePairs = Object.entries(smbObj);
console.log(keyValuePairs);
//["1", "ShowMeBug"]
//["2", "ShowMeMoney"]
| 特性 | Object.keys(obj) | Object.entries(obj) |
|---|---|---|
| 返回內(nèi)容 | 一個(gè)字符串?dāng)?shù)組,包含所有可枚舉的鍵。 | 一個(gè)二維數(shù)組,包含所有可枚舉的 [鍵, 值] 對 |
| 用途 | 獲取對象的所有屬性名 | 獲取對象的所有鍵值對;常用于遍歷或轉(zhuǎn)換為 Map |
| 遍歷 | 需要配合 obj[key] 來獲取值 | 可以直接在 for...of 循環(huán)中解構(gòu)出 key 和 value |
| 順序 | 數(shù)字鍵升序,其他鍵通常為插入順序。 | 與 Object.keys() 順序規(guī)則完全一致。 |
2.Map
用 Map 構(gòu)造函數(shù)創(chuàng)建一個(gè)類似的集合。這一次鍵的初始順序得到了保留
const smbMap = new Map([
[2, 'ShowMeMoney'],
[1, 'ShowMeBug']
]);
const keys = smbMap.keys();
console.log(keys);
//MapIterator {2, 1}
const keyValuePairs = smbMap.entries();
console.log(keyValuePairs);
//MapIterator {2 => "ShowMeMoney", 1 => "ShowMeBug"}
五、Map提供了更好的接口來訪問鍵值對
1.Object獲取
- 訪問對象上的屬性可以通過點(diǎn)運(yùn)算符或方括號運(yùn)算符來完成
- 鍵用的是數(shù)字,只能用方括號運(yùn)算符。
smbObj[1]; //'ShowMeBug'
1.Map獲取
在 Map 上,則需要用
get(key)方法來獲取值
smbMap.get(1); //'ShowMeBug'
2.Object檢查鍵是否存在
對象則可以用
hasOwnProperty(key)方法
smbObj.hasOwnProperty(1); //true smbObj.hasOwnProperty(3); //false
2.Map檢查鍵是否存在
Map可以用has(key)來檢查鍵是否存在
smbMap.has(1); //true smbMap.get(3); //false
3.Object添加鍵值對
對于對象,我們使用方括號或點(diǎn)運(yùn)算符來添加新的鍵值對
smbObj[3] = 'ShowMeFeature';
//{ 1: 'ShowMeBug', 2: 'ShowMeMoney', 3: 'ShowMeFeature'};
3.Map添加鍵值對
set(key, value)在Map中添加新的鍵值對
smbMap.set(3, 'ShowMeFeature');
//{1=>'ShowMeBug', 2=>'ShowMeMoney', 3=>'ShowMeFeature'}
4.Object刪除鍵值對
對象則可以用
delete操作符
delete smbObj[1];
4.Map刪除鍵值對
Map可以通過delete(key)方法來刪除鍵值對
smbMap.delete(1);
5.Object讀取鍵值對數(shù)量
對象沒有獲取鍵值對數(shù)量的特定方法。我們需要使用像Object.keys()這樣的外部幫助函數(shù)
const size = Object.keys(smbObj).length; console.log(size);
5.Map讀取鍵值對數(shù)量
Map有size 屬性來記錄內(nèi)部的鍵值對數(shù)量
console.log(smbMap.size);
六、對象需要幫助函數(shù)來訪問鍵值對
用
forEach方法遍歷 Map中的條目
const smbMap = new Map([
[1, 'ShowMeBug'],
[2, 'ShowMeMoney']
]);
smbMap.forEach((value, key)=>{
console.log(`${key} - ${value}`)
});
//1 - ShowMeBug
//2 - ShowMeMoney對象,我們可以用
Object.entries()輔助函數(shù)進(jìn)行迭代
//Object.entries() 會以 [key, value] 鍵值對數(shù)組的形式返回對象的所有屬性。一旦拿到這一數(shù)組,就能用 forEach 這樣的數(shù)組方法了
const smbObj = {
1: 'ShowMeBug',
2: 'ShowMeMoney'
};
Object
.entries(smbObj)
.forEach(([key, value]) => {
console.log(`${key} - ${value}`)
});
//這里的key,value都是字符串,只是控制臺顯示時(shí)去掉了雙引號
//1 - ShowMeBug
//2 - ShowMeMoney
七、JSON支持對象,但不支持 Map
const smbObj = {
1: 'ShowMeBug',
2: 'ShowMeMoney'
};
const json = JSON.stringify(smbObj);
console.log(json);
//{"1":"ShowMeBug","2":"ShowMeMoney"}
JSON 不支持 Map,序列化的結(jié)果是一個(gè)空對象
const smbMap = new Map([
[1, 'ShowMeBug'],
[2, 'ShowMeMoney']
]);
const json = JSON.stringify(smbMap);
console.log(json);
//{}
八、總結(jié)

- JavaScript 中的對象在其他語言中被稱為哈希映射。訪問映射對象中的鍵所需時(shí)間為 O(1)
- 不管這些鍵值集合是用 Map 構(gòu)造函數(shù)還是對象字面量創(chuàng)建的,它們都主要用于快速搜索數(shù)據(jù),鍵的訪問時(shí)間都是
O(1),檢索鍵也不需要掃描所有數(shù)據(jù)。 - Map 為管理鍵值對提供了更好的接口。在需要添加和刪除條目的場景中,Map 是更好的選擇。而如果創(chuàng)建鍵值集合只是用來搜索鍵時(shí),對象就夠了
到此這篇關(guān)于JavaScript中Map和Object區(qū)別的文章就介紹到這了,更多相關(guān)js Map和Object區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)閉瀏覽器輸入框自動補(bǔ)齊 兼容IE,FF,Chrome等主流瀏覽器
這篇文章主要介紹了關(guān)閉瀏覽器輸入框自動補(bǔ)齊 兼容IE,FF,Chrome等主流瀏覽器,需要的朋友可以參考下。希望對大家有所幫助2014-02-02
JavaScript中你不知道的Object.entries用法
大家應(yīng)該都知道,Object.entries()方法返回一個(gè)給定對象自身可枚舉屬性的鍵值對數(shù)組,其排列與使用 for...in 循環(huán)遍歷該對象時(shí)返回的順序一致,這篇文章主要給大家介紹了關(guān)于JavaScript中你不知道的Object.entries用法的相關(guān)資料,需要的朋友可以參考下2021-10-10
JS實(shí)現(xiàn)點(diǎn)擊網(wǎng)頁判斷是否安裝app并打開否則跳轉(zhuǎn)app store
這篇文章主要介紹了JS實(shí)現(xiàn)點(diǎn)擊網(wǎng)頁判斷是否安裝app并打開否則跳轉(zhuǎn)app store的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
uniapp實(shí)現(xiàn)滾動觸底加載項(xiàng)目實(shí)戰(zhàn)
這篇文章主要為大家介紹了uniapp實(shí)現(xiàn)滾動觸底加載項(xiàng)目實(shí)戰(zhàn)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
JS中使用cavas截圖網(wǎng)頁并解決跨域及模糊問題
這篇文章主要介紹了JS中使用cavas截取網(wǎng)頁并解決跨域以及模糊問題 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11
詳解JavaScript創(chuàng)建數(shù)組的三種方式
這篇文章主要介紹了JavaScript創(chuàng)建數(shù)組的三種方式:直接聲明,?以對象方式創(chuàng)建數(shù)組和使用?Array.from()?方法創(chuàng)建,并通過代碼示例講解的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2024-06-06

