Map 是一种键值对的数据结构,它与普通的对象有所不同。以下是 Map 的特点和常见方法:
1.基本概念
Map 是一个可迭代的对象,保存键值对。
键(key)和值(value)可以是任何类型,包括对象、函数、甚至是 NaN。
Map 中的键是唯一的,但值是可以重复的。
Map 的插入顺序会被记住,这意味着它会按照插入的顺序遍历。
2.创建 Map
你可以通过 new Map() 来创建一个空的 Map 实例,或者通过传递一个包含键值对的二维数组来初始化一个 Map:
// 创建一个空的 Map
const map = new Map();
// 使用二维数组初始化 Map
const map2 = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
console.log(map2); // Map { 'a' => 1, 'b' => 2, 'c' => 3 }
3. 常用方法
set(key, value):向 Map 中添加一个键值对。如果键已经存在,则更新其对应的值。
const map = new Map();
map.set('a', 1);
map.set('b', 2);
map.set('a', 3); // 'a' 对应的值会被更新为 3
console.log(map); // Map { 'a' => 3, 'b' => 2 }
get(key):通过键获取值。如果键不存在,则返回 undefined。
console.log(map.get('a')); // 3
console.log(map.get('b')); // 2
console.log(map.get('c')); // undefined
has(key):判断 Map 中是否包含指定的键。返回 true 或 false。
console.log(map.has('a')); // true
console.log(map.has('c')); // false
delete(key):删除指定的键值对。如果键存在,返回 true,否则返回 false。
map.delete('a');
console.log(map.has('a')); // false
clear():删除 Map 中的所有键值对。
map.clear();
console.log(map.size); // 0
size:获取 Map 中的键值对数量。
console.log(map2.size); // 3
keys()、values()、entries():这些方法分别返回 Map 中键、值、键值对的迭代器。
for (const key of map2.keys()) {
console.log(key); // 'a', 'b', 'c'
}
for (const value of map2.values()) {
console.log(value); // 1, 2, 3
}
for (const [key, value] of map2.entries()) {
console.log(`${key}: ${value}`); // 'a: 1', 'b: 2', 'c: 3'
}
forEach(callback):Map 的 forEach 方法类似于数组的 forEach,它会遍历所有的键值对。
map2.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
// 输出: 'a: 1', 'b: 2', 'c: 3'
4. Map 的优势
任意类型的键:与普通对象只能使用字符串作为键不同,Map 的键可以是任意类型。
const map3 = new Map();
map3.set(1, 'Number');
map3.set(true, 'Boolean');
map3.set({a: 1}, 'Object');
console.log(map3.get(1)); // 'Number'
console.log(map3.get(true)); // 'Boolean'
有序:Map 会记住键值对插入的顺序,这在遍历时非常有用。
const map4 = new Map();
map4.set('a', 1);
map4.set('b', 2);
map4.set('c', 3);
for (const [key, value] of map4) {
console.log(`${key}: ${value}`);
}
// 输出:
// a: 1
// b: 2
// c: 3
5. Map 与对象的区别
特性 Map 普通对象(Object)
键的类型 任何类型(字符串、数字、对象等) 只能是字符串或 Symbol
键值对的顺序 保留插入顺序 无法保证顺序
size 属性 有 size 属性,返回键值对数量 没有直接的 size 属性
是否可迭代 可以直接迭代 需要 Object.keys()、Object.entries() 来迭代
性能(插入与查找) 性能优于普通对象 性能较差(尤其是键较多时)
6. 实际应用示例
计数器:使用 Map 来统计不同项目的数量。
const countMap = new Map();
const items = ['apple', 'banana', 'orange', 'apple', 'banana'];
items.forEach(item => {
if (countMap.has(item)) {
countMap.set(item, countMap.get(item) + 1);
} else {
countMap.set(item, 1);
}
});
console.log(countMap); // Map { 'apple' => 2, 'banana' => 2, 'orange' => 1 }
查找缓存:使用 Map 来实现缓存机制,存储计算结果。
const cache = new Map();
function expensiveComputation(x) {
if (cache.has(x)) {
console.log('Cache hit');
return cache.get(x);
}
console.log('Cache miss');
const result = x * 2; // 模拟耗时计算
cache.set(x, result);
return result;
}
console.log(expensiveComputation(5)); // Cache miss, 10
console.log(expensiveComputation(5)); // Cache hit, 10
小结
Map 是一个功能强大的数据结构,适用于需要频繁查找、插入或删除数据的场景,且支持任何类型的键。
Map 的插入顺序是有保证的,适用于需要按顺序遍历键值对的场景。
通过一些常用方法,如 set、get、delete 等,可以高效地管理键值对。