摘要:在本教程中,您将了解 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); // true
Code 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); // admin
Code language: JavaScript (javascript)
如果您传递一个不存在的键,get()
方法将返回 undefined
。
let foo = {name: 'Foo'};
userRoles.get(foo); //undefined
Code language: JavaScript (javascript)
通过键检查元素是否存在
要检查键是否存在于 map 中,您可以使用 has()
方法。
userRoles.has(foo); // false
userRoles.has(lily); // true
Code language: JavaScript (javascript)
获取 map 中的元素数量
size
属性返回 Map 对象的条目数量。
console.log(userRoles.size); // 3
Code 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); // 0
Code 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 中的条目。