JavaScript Map 对象

摘要:在本教程中,您将了解 JavaScript Map 对象,它将键映射到值。

JavaScript Map 对象简介

在 ES6 之前,我们经常使用 对象 来模拟一个 map,方法是将一个键映射到任何类型的 value。 但是将对象用作 map 有一些副作用

  1. 一个对象总是具有默认键,例如 原型
  2. 对象的键必须是 字符串符号,您不能使用对象作为键。
  3. 对象没有表示 map 大小的属性。

ES6 提供了一种称为 Map 的新集合类型来解决这些缺陷。

根据定义,Map 对象保存键值对。 键在 Map 的集合中是唯一的。 换句话说,Map 对象中的键只出现一次。

Map 的键和值可以是任何值。

当迭代 Map 对象时,每次迭代都会返回一个包含 [key, value] 的 2 元数组。 迭代顺序遵循插入顺序,这对应于每个键值对第一次通过 set() 方法插入到 Map 中的顺序。

要创建一个新的 Map,您可以使用以下语法

let map = new Map([iterable]);Code language: JavaScript (javascript)

Map() 接受一个可选的 可迭代 对象,其元素是键值对。

有用的 JavaScript Map 方法

  • clear() – 从 map 对象中删除所有元素。
  •  delete(key) – 删除由键指定的元素。 如果元素在 map 中,则返回 true,否则返回 false。
  •  entries() – 返回一个新的 Iterator 对象,该对象包含 map 对象中每个元素的 [key, value] 数组。 map 中对象的顺序与插入顺序相同。
  •  forEach(callback[, thisArg]) – 以插入顺序对 map 中的每个键值对调用回调。 可选的 thisArg 参数为每个回调设置 this 值。
  •  get(key) – 返回与键关联的值。 如果键不存在,则返回 undefined。
  •  has(key) – 如果与键关联的值存在,则返回 true,否则返回 false。
  •  keys() – 返回一个新的 Iterator,该 Iterator 包含元素的键,以插入顺序排列。
  •  set(key, value) – 设置 map 对象中键的值。 它返回 map 对象本身,因此您可以将此方法与其他方法链接起来。
  •  values() 返回一个新的 Iterator 对象,该对象包含每个元素的值,以插入顺序排列。

JavaScript Map 示例

让我们看一些使用 Map 对象的示例。

创建一个新的 Map 对象

假设您有一个 user 对象列表,如下所示

let john = {name: 'John Doe'},
    lily = {name: 'Lily Bush'},
    peter = {name: 'Peter Drucker'};Code language: JavaScript (javascript)

假设您必须创建用户和角色的映射。 在这种情况下,您使用以下代码

let userRoles = new Map();Code language: JavaScript (javascript)

userRolesMap 对象的一个实例,它的类型是一个对象,如以下示例所示

console.log(typeof(userRoles)); // object
console.log(userRoles instanceof Map); // trueCode language: JavaScript (javascript)

向 Map 添加元素

要为用户分配角色,您可以使用 set() 方法

userRoles.set(john, 'admin');Code language: JavaScript (javascript)

set() 方法将用户 johnadmin 角色映射。 由于 set() 方法是可链接的,因此您可以像本示例中所示那样节省一些输入

userRoles.set(lily, 'editor')
          .set(peter, 'subscriber');
Code language: JavaScript (javascript)

使用可迭代对象初始化 map

如前所述,您可以将可迭代对象传递给 Map() 构造函数

let userRoles = new Map([
    [john, 'admin'],
    [lily, 'editor'],
    [peter, 'subscriber']
]);Code language: JavaScript (javascript)

通过键从 map 中获取元素

如果您想查看 John 的角色,您可以使用 get() 方法

userRoles.get(john); // adminCode language: JavaScript (javascript)

如果您传递一个不存在的键,get() 方法将返回 undefined

let foo = {name: 'Foo'};
userRoles.get(foo); //undefinedCode language: JavaScript (javascript)

通过键检查元素是否存在

要检查键是否存在于 map 中,您可以使用 has() 方法。

userRoles.has(foo); // false
userRoles.has(lily); // trueCode language: JavaScript (javascript)

获取 map 中的元素数量

size 属性返回 Map 对象的条目数量。

console.log(userRoles.size); // 3Code language: JavaScript (javascript)

遍历 map 键

要获取 Map 对象的键,您可以使用 keys() 方法。 keys() 返回一个新的 迭代器 对象,该对象包含 map 中元素的键。

以下示例显示 userRoles map 对象中用户的用户名。

let john = { name: 'John Doe' },
  lily = { name: 'Lily Bush' },
  peter = { name: 'Peter Drucker' };

let userRoles = new Map([
  [john, 'admin'],
  [lily, 'editor'],
  [peter, 'subscriber'],
]);

for (const user of userRoles.keys()) {
  console.log(user.name);
}Code language: JavaScript (javascript)

输出

John Doe
Lily Bush
Peter Drucker

遍历 map 值

类似地,您可以使用 values() 方法获取一个迭代器对象,该对象包含 map 中所有元素的值

let john = { name: 'John Doe' },
  lily = { name: 'Lily Bush' },
  peter = { name: 'Peter Drucker' };

let userRoles = new Map([
  [john, 'admin'],
  [lily, 'editor'],
  [peter, 'subscriber'],
]);

for (let role of userRoles.values()) {
  console.log(role);
}Code language: JavaScript (javascript)

输出

admin
editor
subscriber

遍历 map 元素

此外,entries() 方法返回一个迭代器对象,该对象包含 Map 对象中每个元素的 [key,value] 数组

let john = { name: 'John Doe' },
  lily = { name: 'Lily Bush' },
  peter = { name: 'Peter Drucker' };

let userRoles = new Map([
  [john, 'admin'],
  [lily, 'editor'],
  [peter, 'subscriber'],
]);

for (const role of userRoles.entries()) {
  console.log(`${role[0].name}: ${role[1]}`);
}Code language: JavaScript (javascript)

为了使迭代更加自然,您可以使用 解构,如下所示

let john = { name: 'John Doe' },
  lily = { name: 'Lily Bush' },
  peter = { name: 'Peter Drucker' };

let userRoles = new Map([
  [john, 'admin'],
  [lily, 'editor'],
  [peter, 'subscriber'],
]);

for (let [user, role] of userRoles.entries()) {
  console.log(`${user.name}: ${role}`);
}
Code language: JavaScript (javascript)

除了 for...of 循环之外,您还可以使用 map 对象的 forEach() 方法

let john = { name: 'John Doe' },
  lily = { name: 'Lily Bush' },
  peter = { name: 'Peter Drucker' };

let userRoles = new Map([
  [john, 'admin'],
  [lily, 'editor'],
  [peter, 'subscriber'],
]);

userRoles.forEach((role, user) => console.log(`${user.name}: ${role}`));Code language: JavaScript (javascript)

将 map 键或值转换为数组

有时,您想使用数组而不是可迭代对象,在这种情况下,您可以使用 扩展运算符

以下示例将每个元素的键转换为键数组

var keys = [...userRoles.keys()];
console.log(keys);Code language: JavaScript (javascript)

输出

[ { name: 'John Doe' },
  { name: 'Lily Bush' },
  { name: 'Peter Drucker' } ]Code language: JavaScript (javascript)

以下将元素的值转换为数组

let roles = [...userRoles.values()];
console.log(roles);Code language: JavaScript (javascript)

输出

[ 'admin', 'editor', 'subscriber' ]Code language: JSON / JSON with Comments (json)

通过键删除元素

要删除 map 中的条目,您可以使用 delete() 方法。

userRoles.delete(john);Code language: CSS (css)

删除 map 中的所有元素

要删除 Map 对象中的所有条目,您可以使用 clear() 方法

userRoles.clear();Code language: CSS (css)

因此,map 的大小现在为零。

console.log(userRoles.size); // 0Code language: JavaScript (javascript)

WeakMap

WeakMap 类似于 Map,只是 WeakMap 的键必须是对象。 这意味着,当对键(对象)的引用超出范围时,相应的值会自动从内存中释放。

WeakMap 只有 Map 对象的子集方法

  •  get(key)
  •  set(key, value)
  •  has(key)
  •  delete(key)

以下是 MapWeekMap 之间的主要区别

  • 无法迭代 WeakMap 的元素。
  • 无法一次清除所有元素。
  • 无法检查 WeakMap 的大小。

在本教程中,您已经学习了如何使用 JavaScript Map 对象及其有用的方法来操作 map 中的条目。

本教程对您有帮助吗?