摘要:在本教程中,您将了解 JavaScript Map 对象,它将键映射到值。
JavaScript Map 对象简介
在 ES6 之前,我们经常使用 对象 来模拟一个 map,方法是将一个键映射到任何类型的 value。 但是将对象用作 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)userRoles 是 Map 对象的一个实例,它的类型是一个对象,如以下示例所示
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() 方法将用户 john 与 admin 角色映射。 由于 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)
以下是 Map 和 WeekMap 之间的主要区别
- 无法迭代 WeakMap 的元素。
- 无法一次清除所有元素。
- 无法检查 WeakMap 的大小。
在本教程中,您已经学习了如何使用 JavaScript Map 对象及其有用的方法来操作 map 中的条目。