一个表带你读懂 Map和 Object 的区别

在我们日常开发中 Object 使用到的频率出奇的高,而MapObject 类似,都允许按 键-值(key-value)对储数据,也可以对一个键进行删除和检测该键值是否存在。诚然在 ES2015 之前我们只能通过 Object 的形式来存储键值对的数据结构,但是现在已经是3202年了,是时候尝试用 Map 来代替 Object 作为 键值对数据结构的唯一选择了。

MapObject
额外的键Map 默认情况下不包含任何键值。只会包含显示插入的键一个 Object 有一个原型,原型链上的键名可能和专家对象上设置的键名产生冲突 (tips: 可以使用 Object.create(null) 来创建一个没有原型的对象)
键的类型一个 Map 的键可以是任意值,包括函数、对象或任意基本类型一个 Object 的键必须是一个 String 或者是 Symbol
键的顺序Map 中的键是有序的。因此,在迭代的时候,一个Map 对象以插入的顺序返回键值虽然 Object 的键目前是有序的,但并不总是这样,而且这个顺序是复杂的。因此,最好不要依赖属性的顺序。

自 ECMAScript 2015 规范以来,对象的属性被定义为是有序的;ECMAScript 2020 则额外定义了继承属性的顺序。参见 OrdinaryOwnPropertyKeysEnumerateObjectProperties 抽象规范说明。但是,请注意没有可以迭代对象所有属性的机制,每一种机制只包含了属性的不同子集。(for-in 仅包含了以字符串为键的属性;Object.keys 仅包含了对象自身的、可枚举的、以字符串为键的属性;Object.getOwnPropertyNames 包含了所有以字符串为键的属性,即使是不可枚举的;Object.getOwnPropertySymbols 与前者类似,但其包含的是以 Symbol 为键的属性,等等。)
大小Map 的键值对个数可以轻易地通过 size 属性获取。Object 的键值对个数只能手动计算
迭代Map可迭代的 的,所以可以直接被迭代。Object 没有实现 迭代协议,所以使用 JavaSctipt 的 for…of 表达式并不能直接迭代对象。
tips:
对象可以实现迭代协议,或者你可以使用 Object.keysObject.entries
for…in 表达式允许你迭代一个对象的可枚举属性
性能在频繁增删键值对的场景下表现更好。在频繁添加和删除键值对的场景下未作出优化。
序列化和解析没有元素的序列化和解析的支持。
(但是你可以使用携带 replacer 参数的 JSON.stringify() 创建一个自己的对 Map 的序列化和解析支持。
原生的由 Object 到 JSON 的序列化支持,使用 JSON.stringify()
原生的由 JSON 到 Object 的解析支持,使用 JSON.parse()

设置对象属性

设置对象属性同样适用于 Map 对象,但容易造成困扰。

即,以下的代码能够正常运行(但不推荐):

const wrongMap = new Map();
wrongMap['bla'] = 'blaa';
wrongMap['bla2'] = 'blaaa2';

console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }

但这种设置属性的方式不会改变 Map 的数据结构。它使用的是通用对象的特性。'bla' 的值未被存储在 Map 中,无法被查询到。其他的对这一数据的操作也会失败:

wrongMap.has('bla')    // false
wrongMap.delete('bla') // false
console.log(wrongMap)  // Map { bla: 'blaa', bla2: 'blaaa2' }

正确的存储数据到 Map 中的方式是使用 set(key, value) 方法。

const contacts = new Map()
contacts.set('Jessie', {phone: "213-555-1234", address: "123 N 1st Ave"})
contacts.has('Jessie') // true
contacts.get('Hilary') // undefined
contacts.set('Hilary', {phone: "617-555-4321", address: "321 S 2nd St"})
contacts.get('Jessie') // {phone: "213-555-1234", address: "123 N 1st Ave"}
contacts.delete('Raymond') // false
contacts.delete('Jessie') // true
console.log(contacts.size) // 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值