传统上,存储键值对的数据结构时,对象 (Object) 一直是我们的首选。然而,ES6 引入了 Map
对象,它提供了一种更强大、更灵活的方式来处理键值对。以前也懒得用,直到最近用了下,我发现 Map 比对象更香 。
1. 键的类型不再局限:
这是 Map 最显著的优势之一。对象只能使用字符串或 Symbol 作为键,这限制了其适用性。Map 则不同,
可以使用任何数据类型作为键,包括对象、函数、数字,甚至 NaN 。想象一下,你想要使用 DOM 元素作为键来存储与其相关的数据,Map 可以轻松实现:

对象则无法实现这种灵活的键类型。
2. 键的顺序得到保留:
对象的属性在添加时,其顺序是不确定的,尤其是在较旧的 JavaScript 引擎中。虽然现代 JavaScript
引擎尝试保留属性的插入顺序,但这种行为并非总是可靠的。Map 则不同, Map 对象会按照键值对插入的顺序进行存储和迭代
。这在需要维护特定顺序的场景下非常有用:

3. 轻松获取大小:
要获取对象中属性的数量,你需要手动遍历或者使用 Object.keys(obj).length ,这既不优雅,也可能效率不高。Map
对象提供了一个简单的 size 属性,可以 直接获取键值对的数量 :

4. 避免原型链污染:
JavaScript
对象会继承原型链上的属性。这意味着,如果不小心,你可能会意外访问到原型链上的属性,或者更糟糕的是,修改原型链上的属性,导致全局污染。Map
对象不会继承任何属性,它 完全隔离于原型链 ,更加安全可靠。
5. 更优的性能:
在某些场景下,特别是需要频繁添加、删除键值对的情况下,Map 对象通常比对象具有 更好的性能 。JavaScript 引擎对 Map
对象进行了专门的优化,使其更适合处理动态数据。
6. 内置的迭代方法:
Map 对象提供了内置的迭代方法,例如 forEach 、 keys 、 values 和 entries ,使得
迭代键值对变得非常方便 :
const myMap = new Map();
myMap.set('a', 1);
myMap.set('b', 2);
myMap.forEach((value, key) => {
console.log(key, value); // 输出: a 1, b 2
});
for (const key of myMap.keys()) {
console.log(key); // 输出: a, b
}
for (const value of myMap.values()) {
console.log(value); // 输出: 1, 2
}
for (const [key, value] of myMap.entries()) {
console.log(key, value); // 输出: a 1, b 2
}
何时仍然使用对象?
虽然 Map 在很多方面都优于对象,但对象仍然有其用武之地。
JSON: JSON 数据格式本质上是对象。
简单的配置对象: 对于简单的、静态的配置对象,对象仍然是一个不错的选择。
需要直接访问属性的情况: 如果需要使用
obj.propertyName语法直接访问属性,对象仍然是必要的。但是,请注意,这可以通过将 Map 转换为对象来实现,但需要权衡性能。
欢迎补充。