JavaScript中Map和Object的区别详解
作者:I'mxx
Map 和 Object 都是 JavaScript 中用于存储键值对的数据结构,这篇文章主要介绍了JavaScript中Map和Object区别的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
一、构造方式不同
在js中创建object最简单的方法是通过字面量
(对象/对象映射)
const smbObj = { 1: 'ShowMeBug', 2: 'ShowMeMoney' };
Map
则是通过内置构造函数Map创建
(映射)
const smbMap = new Map([ [1, 'ShowMeBug'], [2, 'ShowMeMoney'] ]);
二、对象中的键是字符串,映射中的键可以是任意类型
- object是键值对的集合,但键只能是字符串。
- 比如,如果用数字作 Object 的键,则该数字将转换为字符串
- 而Map的键可以是任意类型
- 无论是对象还是映射,键都是唯一的。对象中不能有两个相同键的属性,映射中也不能有两个相同键的条目。
在Object中:
//因为键已经被转换成字符串,所以无论是获取数字1还是字符串'1'的值时,得到的结果都一样 console.log(smbObj[1]); //'ShowMeBug' console.log(smbObj['1']); //'ShowMeBug'
在Map中:
//Map 的键可以为任意类型,数字 1 的键和字符串 '1' 的键并不一样 console.log(smbMap[1]); //'ShowMeBug' console.log(smbMap['1']); //undefined
三、对象会从原型中继承多余的键
- 使用字面量创建的 Object 会继承一组来自 Object.prototype 的键值对
1.继承Object.prototype键值对
//打印 Object.prototype, //你会发现它还有 //hasOwnProperty、 //isPrototypeOf、 //toLocaleString、 //toString 等属性 console.log(Object.prototype);
2.创建{},会继承Object.prototype
- 当你创建一个普通对象 {} 时,它会自动继承自 Object.prototype
- 因此,即使你的对象 {} 看起来是“空”的,它也能访问到这些继承来的方法。当你访问 socalledEmptyObject[‘toString’] 时,JavaScript 引擎首先在对象自身上查找 toString 属性,没找到,然后沿着原型链向上查找,在 Object.prototype 上找到了它,所以返回了该函数。
const socalledEmptyObject = {}; console.log(socalledEmptyObject['toString']); //ƒ toString() { [native code] }
3.创建对象映射最好用Object.create(null) 来做
//Object.create(null) 能构建出没有原型的对象 const emptyObject = Object.create(null); console.log(emptyObject['toString']); //undefined
四、Map 会保留键的顺序,对象不会
1.Object
创建对象时,键 2 出现在键 1 之前。
但在检索所有键时,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) |
---|---|---|
返回内容 | 一个字符串数组,包含所有可枚举的键。 | 一个二维数组,包含所有可枚举的 [键, 值] 对 |
用途 | 获取对象的所有属性名 | 获取对象的所有键值对;常用于遍历或转换为 Map |
遍历 | 需要配合 obj[key] 来获取值 | 可以直接在 for...of 循环中解构出 key 和 value |
顺序 | 数字键升序,其他键通常为插入顺序。 | 与 Object.keys() 顺序规则完全一致。 |
2.Map
用 Map 构造函数创建一个类似的集合。这一次键的初始顺序得到了保留
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获取
- 访问对象上的属性可以通过点运算符或方括号运算符来完成
- 键用的是数字,只能用方括号运算符。
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添加键值对
对于对象,我们使用方括号或点运算符来添加新的键值对
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读取键值对数量
对象
没有获取键值对数量的特定方法。我们需要使用像Object.keys()
这样的外部帮助函数
const size = Object.keys(smbObj).length; console.log(size);
5.Map读取键值对数量
Map
有size 属性
来记录内部的键值对数量
console.log(smbMap.size);
六、对象需要帮助函数来访问键值对
用
forEach
方法遍历 Map
中的条目
const smbMap = new Map([ [1, 'ShowMeBug'], [2, 'ShowMeMoney'] ]); smbMap.forEach((value, key)=>{ console.log(`${key} - ${value}`) }); //1 - ShowMeBug //2 - ShowMeMoney
对象,我们可以用
Object.entries()
辅助函数进行迭代
//Object.entries() 会以 [key, value] 键值对数组的形式返回对象的所有属性。一旦拿到这一数组,就能用 forEach 这样的数组方法了 const smbObj = { 1: 'ShowMeBug', 2: 'ShowMeMoney' }; Object .entries(smbObj) .forEach(([key, value]) => { console.log(`${key} - ${value}`) }); //这里的key,value都是字符串,只是控制台显示时去掉了双引号 //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,序列化的结果是一个空对象
const smbMap = new Map([ [1, 'ShowMeBug'], [2, 'ShowMeMoney'] ]); const json = JSON.stringify(smbMap); console.log(json); //{}
八、总结
- JavaScript 中的对象在其他语言中被称为哈希映射。访问映射对象中的键所需时间为 O(1)
- 不管这些键值集合是用 Map 构造函数还是对象字面量创建的,它们都主要用于快速搜索数据,键的访问时间都是
O(1)
,检索键也不需要扫描所有数据。 - Map 为管理键值对提供了更好的接口。在需要添加和删除条目的场景中,Map 是更好的选择。而如果创建键值集合只是用来搜索键时,对象就够了
到此这篇关于JavaScript中Map和Object区别的文章就介绍到这了,更多相关js Map和Object区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!