前端开发必备:JavaScript Map 详解 – wiki大全


前端开发必备:JavaScript Map 详解

在现代 JavaScript 开发中,我们经常需要处理键值对数据。传统上,我们使用 Object 来存储这类数据。然而,ES6 引入的 Map 数据结构,为键值对存储提供了更强大、更灵活的解决方案。本文将深入探讨 Map 的特性、用法以及它与 Object 的区别,帮助你更好地理解和运用 Map

什么是 JavaScript Map?

Map 是一种新的集合类型,它存储键值对,并且与 Object 不同的是,它的键可以是任意数据类型(包括对象、函数等),而不仅仅是字符串或 Symbol。Map 会记住键值对的原始插入顺序,这在某些场景下非常有用。

Map 的主要特性:

  1. 任意类型的键 (Keys of Any Type):这是 Map 最显著的优势。你可以使用任何 JavaScript 值作为键,包括对象和原始值。
  2. 保持插入顺序 (Preserves Insertion Order)Map 实例会按照键值对的插入顺序进行迭代。
  3. 可迭代 (Iterable)Map 是可迭代对象,可以通过 for...of 循环、forEach 方法等进行遍历。
  4. size 属性 (Size Property)Map 提供了 size 属性来轻松获取其包含的键值对数量,这比计算 Object 的属性数量更直接。
  5. 性能 (Performance):在频繁添加和删除键值对的场景下,Map 通常比 Object 具有更好的性能。

如何使用 Map?

1. 创建 Map

使用 new Map() 构造函数可以创建一个新的 Map。你也可以传入一个可迭代对象(例如数组),其中每个元素都是一个包含两个元素的数组([key, value]),用于初始化 Map

“`javascript
// 创建一个空的 Map
const myMap = new Map();
console.log(myMap.size); // 0

// 使用数组初始化 Map
const initialData = [
[‘name’, ‘Alice’],
[‘age’, 30],
[1, ‘one’],
[{}, ‘an object key’]
];
const anotherMap = new Map(initialData);
console.log(anotherMap.size); // 4
“`

2. 添加和更新元素 (set())

使用 map.set(key, value) 方法可以向 Map 中添加新的键值对。如果 key 已经存在,则会更新其对应的值。set() 方法返回 Map 实例本身,因此可以链式调用。

“`javascript
const userRoles = new Map();

userRoles.set(‘admin’, true);
userRoles.set(‘editor’, false);
userRoles.set(‘viewer’, true);

console.log(userRoles); // Map(3) {“admin” => true, “editor” => false, “viewer” => true}

// 更新现有键的值
userRoles.set(‘editor’, true);
console.log(userRoles.get(‘editor’)); // true

// 链式调用
userRoles.set(‘guest’, true).set(‘super_admin’, false);
console.log(userRoles.size); // 5
“`

3. 获取元素 (get())

使用 map.get(key) 方法可以根据键获取对应的值。如果键不存在,则返回 undefined

“`javascript
const userSettings = new Map();
userSettings.set(‘theme’, ‘dark’);
userSettings.set(‘notifications’, true);

console.log(userSettings.get(‘theme’)); // “dark”
console.log(userSettings.get(‘notifications’)); // true
console.log(userSettings.get(‘language’)); // undefined
“`

4. 检查元素是否存在 (has())

使用 map.has(key) 方法可以检查 Map 中是否存在指定的键,返回一个布尔值。

“`javascript
const inventory = new Map();
inventory.set(‘apple’, 10);
inventory.set(‘banana’, 5);

console.log(inventory.has(‘apple’)); // true
console.log(inventory.has(‘orange’)); // false
“`

5. 删除元素 (delete())

使用 map.delete(key) 方法可以从 Map 中删除指定的键值对。如果删除成功,返回 true;如果键不存在,返回 false

“`javascript
const tasks = new Map();
tasks.set(1, ‘Buy groceries’);
tasks.set(2, ‘Pay bills’);

console.log(tasks.delete(1)); // true
console.log(tasks.has(1)); // false
console.log(tasks.delete(3)); // false (键 3 不存在)
“`

6. 清空 Map (clear())

使用 map.clear() 方法可以移除 Map 中的所有键值对。

“`javascript
const cache = new Map([
[‘data1’, { id: 1 }],
[‘data2’, { id: 2 }]
]);
console.log(cache.size); // 2

cache.clear();
console.log(cache.size); // 0
“`

遍历 Map

Map 是一个可迭代对象,提供了多种遍历方式。

1. 使用 for...of 循环

你可以直接通过 for...of 循环遍历 Map 的所有键值对,每个迭代项是一个 [key, value] 数组。

“`javascript
const scores = new Map([
[‘Alice’, 95],
[‘Bob’, 88],
[‘Charlie’, 92]
]);

for (const [name, score] of scores) {
console.log(${name}: ${score});
}
// 输出:
// Alice: 95
// Bob: 88
// Charlie: 92
“`

2. keys(), values(), entries() 方法

Map 提供了三个迭代器方法,分别用于获取键、值或键值对。

  • map.keys():返回一个可迭代的 MapIterator 对象,其中包含 Map 中所有键。
  • map.values():返回一个可迭代的 MapIterator 对象,其中包含 Map 中所有值。
  • map.entries():返回一个可迭代的 MapIterator 对象,其中包含 Map 中所有键值对([key, value] 数组)。

“`javascript
const productPrices = new Map([
[‘laptop’, 1200],
[‘keyboard’, 75],
[‘mouse’, 30]
]);

console.log(‘— Keys —‘);
for (const product of productPrices.keys()) {
console.log(product);
}
// 输出:
// laptop
// keyboard
// mouse

console.log(‘— Values —‘);
for (const price of productPrices.values()) {
console.log(price);
}
// 输出:
// 1200
// 75
// 30

console.log(‘— Entries —‘);
for (const entry of productPrices.entries()) {
console.log(entry); // 例如:[“laptop”, 1200]
}
“`

3. forEach() 方法

Map 也提供了 forEach() 方法,与 Array.prototype.forEach() 类似,它为 Map 中的每个键值对执行一次提供的回调函数。回调函数的参数顺序是 (value, key, map)

“`javascript
const students = new Map();
students.set(‘ID001’, ‘John Doe’);
students.set(‘ID002’, ‘Jane Smith’);

students.forEach((name, id) => {
console.log(Student ID: ${id}, Name: ${name});
});
// 输出:
// Student ID: ID001, Name: John Doe
// Student ID: ID002, Name: Jane Smith
“`

Map 与 Object 的区别和选择

MapObject 都可以用于存储键值对,但它们之间存在关键差异,决定了在不同场景下应该选择哪个。

| 特性 | Map | Object |
| :

滚动至顶部