JavaScript Map 的优点
我之前写过一篇关于JavaScript Set 对象的博客文章,所以很自然地想接着写一篇关于 JavaScript Map 对象的文章。Set 和 Map 可以说是更流行、更强大的 Array 和 Object 的远房表亲,甚至是疏远的兄弟,而 Map 则更像是 Object/Array 的混合体(好吧,可能只有我这么认为)。
Map 是在 ECMAScript 2015 的更新中引入的,它是一个可迭代的键值集合,它能够记住键的原始插入顺序,并始终保持该顺序。
与物体的相似之处
对象与 Map 类似,因为这两种数据结构都允许设置键/值对并检索这些值。您还可以删除键并判断当前键上是否存储了内容。MDN Web 文档指出,由于没有内置替代方案,对象过去一直被用作 Map 。
与对象的区别
Map 和 Object 之间的以下差异可能会使 Map 在特定情况下更受欢迎:
主要区别(明白了吗?)
保留插入顺序是 Map 的一大优势,因为 Map 会维护条目的顺序。对象本身并没有保证的顺序,但是 MDN 文档指出:“自 ECMAScript 2015 以来,对象会保留字符串和符号键的创建顺序。在符合 ECMAScript 2015 规范的 JavaScript 引擎中,仅使用字符串键迭代对象将按插入顺序生成键。”
关于默认键,Map 只会包含你明确输入的内容,因此不会出现意外的默认键。由于 Object 具有原型,它包含的默认键可能会与你自定义的键冲突,因此需要注意这一点。
在 Map 中,键值对的灵活性更高,因为键可以是任何值,例如函数、对象和基元。在 Object 中,键只能是字符串或符号。根据您存储数据的方式,Map 对更多数据类型的灵活性可能会很有用。
虽然 Map 中的键是唯一的,但当使用对象作为键时,Map 会使用对象的引用来检查相等性。需要注意的是,如果两个对象具有相同的值,但不共享相同的引用,则它们将被视为不相等。
const obj1 = {'favorite': 'New Zealand'};
const obj2 = {'favorite': 'New Zealand'};
obj1 === obj2; // false
const map = new Map();
map.set(obj1, 2); // Map { {favorite: 'New Zealand'} => 2 }
map.set(obj2, 2); // Map { {favorite: 'New Zealand'} => 2, {favorite: 'New Zealand'} => 2 }
map.set({'favorite': 'New Zealand'}, 2); // Map { {favorite: 'New Zealand'} => 2, {favorite: 'New Zealand'} => 2,
//{favorite: 'New Zealand'} => 2 }
其他重要差异
Map 的其他优势包括其size
属性,可以轻松获取 Map 中项目的数量。而使用 Object 时,则需要自行确定其大小。
可以直接对 Map 进行迭代,这与对象不同,在对象中您必须获取键/值/条目(通常作为数组),然后对这些值进行迭代。
与未针对这些操作进行优化的对象相比,Map 在频繁添加甚至删除键值对方面具有优势。
入门
以下是如何初始化一个新 Map:
const travelMap = new Map();
travelMap; // Map {}
您还可以使用现有数组(使用嵌套数组)或对象初始化 Map。
const myArray = [
['Asia', 6],
['Europe', 6],
['Other', 3]
];
const travelMap = new Map(myArray);
const myObject = {
'Asia': 6,
'Europe': 6,
'Other': 3
};
const travelMap = new Map(Object.entries(myObject));
travelMap; // Map {'Asia' => 6, 'Europe' => 6, 'Other' => 3}
地图属性和方法
要向 Map 添加新的键/值对,该set()
方法接受两个参数:键和值,并返回 Set 对象。该size()
属性返回 Map 中键/值对的数量:
Map.prototype.set(key, value);
travelMap.set('Asia', 6); // Map {'Asia' => 6}
travelMap.set('Europe', 6); // Map {'Asia' => 6, 'Europe' => 6}
travelMap.set('Other', 3); // Map {'Asia' => 6, 'Europe' => 6, 'Other' => 3}
travelMap.size; // 3
其他有用的方法包括has()
返回一个布尔值,指示 Map 对象中是否存在某个键。
travelMap.has('Asia'); //true
travelMap.has('Antarctica'); //false
get()
使用其键检索 Map 中的值。
travelMap.get('Asia'); // 6
delete()
has()
删除传入的元素并返回应返回的值(true
表示删除成功)。用于has()
检查是否删除了元素将返回 false。
travelMap.delete('Europe'); // true
travelMap; // Map {'Asia' => 6, 'Other' => 3};
travelMap.has('Europe'); // false
travelMap.size // 2
如果您需要删除 Map 中的所有元素,则可以使用clear()
。
travelMap.clear();
travelMap; // Map {}
forEach()
您可以直接使用或循环来迭代 Map 中的键/值对for..of
。
//using forEach
travelMap.forEach((value, key) =>
console.log(`Number of Countries Visited in ${key} : ${value}`)
);
//using for..of loop
for (let [key, value] of travelMap) {
console.log(`Number of Countries Visited in ${key} : ${value}`)
};
// 'Number of Countries Visited in Asia: 6
// 'Number of Countries Visited in Europe: 6
// 'Number of Countries Visited in Other: 3
与 Object 相比,使用 Map 有很多优势(例如 size 属性、可直接迭代以及记住插入顺序),因此在决定使用哪种数据结构时,务必权衡利弊。祝您编码愉快!
资源
图 - JavaScript | MDN
理解 JavaScript 中的 Map 和 Set