Skip to main content

Map

Map 是一种新的集合类型,可以用来存储 键值对, 并且能够记住键的原始插入顺序

Map 中的 一个键只能出现一次; 它在 Map 的集合中是独一无二的。

初始化

如果想在创建的时候初始化实例 , 可以给 Map 构造函数 传入一个 Array 或者可迭代对象

const map = new Map();

嵌套数组

const map = new Map([
[1, "one"],
[2, "two"],
[3, "three"],
]);

console.log(map.get(1)); //one

复制 Maps

const original = new Map([[1, "one"]]);

const clone = new Map(original);

console.log(clone.get(1)); // one
console.log(original === clone); // false 因为是不同对象的引用

合并 Maps

const first = new Map([
[1, "one"],
[2, "two"],
[3, "three"],
]);

const second = new Map([
[1, "uno"],
[2, "dos"],
]);

// 合并两个 Map 对象时,如果有重复的键值,则后面的会覆盖前面的。
// 展开语法本质上是将 Map 对象转换成数组。
const merged = new Map([...first, ...second]);

console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos

基本 API

可以使用 set() 在添加 键值对set() 方法返回 Map 实例, 因此 可以把 多个操作 连接 起来。

可以使用 get()has() 进行查询。可以通过 size 属性获取 Map键值对的数量。

可以使用 delete()clear() 删除值。

const map = new Map();

console.log(map.has("firstName")); // false
console.log(map.get("firstName")); // undefined
console.log(map.size); // 0

map.set("firstName", "Matt").set("lastName", "Frisbie");

console.log(map.has("firstName")); // true
console.log(map.get("firstName")); // Matt
console.log(map.size); // 2

map.delete("firstName");

console.log(map.has("firstName")); // false
console.log(map.has("lastName")); // Frisbie
console.log(map.size); // 1

map.clear();

console.log(map.has("firstName")); // false
console.log(map.has("lastName")); // Frisfalsebie
console.log(map.size); // 0

Map 可以使用任何 Javascript 数据类型 作为

基本上相当于使用 严格对象相等 的标准检查 的匹配性。

const map = new Map();

const functionKey = () => {};
const symbolKey = Symbol();
const objectKey = {};

map.set(functionKey, "functionValue");
map.set(symbolKey, "symbolValue");
map.set(objectKey, "objectValue");

console.log(map.get(functionKey)); // functionValue
console.log(map.get(symbolKey)); // symbolValue
console.log(map.get(objectKey)); // objectValue

顺序与迭代

Map 实例会维护 键值对 的插入顺序, 因此可以根据 插入顺序 执行迭代操作。

const map = new Map([
["key1", "value1"],
["key2", "value2"],
["key3", "value3"],
]);

for (const [key, value] of map.entries()) {
console.log(key, value);
}

entries() 是默认迭代器, 因为map.entries 全等 map[Symbol.iterator] 所以可以直接对 Map 进行扩展操作。

Map 转换成数组:

const map = new Map([
["key1", "value1"],
["key2", "value2"],
["key3", "value3"],
]);

console.log([...map]); // [["key1", "value1"],["key2", "value2"],["key3", "value3"]]

可以调用Map实例的forEach()方法,一次迭代每个键值对

const map = new Map([
["key1", "value1"],
["key2", "value2"],
["key3", "value3"],
]);

map.forEach((value, key) => {
console.log(value, key);
});

// value1 key1
// value2 key2
// value3 key3

keys()values()分别返回插入顺序生成的迭代器

const map = new Map([
["key1", "value1"],
["key2", "value2"],
["key3", "value3"],
]);

console.log(Array.from(map.keys())); // ['key1','key2','key3']
console.log(Array.from(map.values())); // ['value1','value2','value3']

Map 和 Object 的区别

内存占用

Map 大约可以比 Object 多存储 50%键值对

插入性能

涉及到 大量 插入操作 Map的性能会比Object更好一点。

删除性能

使用 delete 关键字删除属性的性能一直饱受诟病。所以出现了一些把属性值设置为 nullundefined

涉及到 大量 删除操作 Map , Map 的性能会比 Object 更好一点。