最近项目闲了,领导有事儿没事儿就进行代码评审。看完我的代码后,领导问我,你的代码怎么全是对Object 增删查改审,你怎么不用new Map()
呢,我都审美疲劳了!
我没用过,但我要装作我知道,于是我赶忙解释,对直接进行对象操作写的代码直观易懂啊!领导还真被我唬住了,哈哈。
后来浅浅研究一下,没想到new Map()
用起来确实更优雅!好用,爱用!
为什么要用 new Map
?
当我第一次认真用 Map
,有点像发现了新大陆。Map
是 JavaScript 提供的一种键值对集合。在处理键值对时,它的这些优点真的令我上头:
- 键可以是任何类型
不像普通对象的键只能是字符串或 symbol,Map
的键可以是对象、数组、函数,甚至是 NaN!
js
const map = new Map();
map.set({}, 'hello'); // 对象也能做 key(注意,你没有对象)!
- 顺序可控,操作清晰
Map
保留插入顺序,遍历也很优雅:
js
for (const [key, value] of map) {
console.log(key, value);
}
比起 Object 还要 Object.keys()
+ 再去 index 取值,Map
简直是优雅代名词 💅
- 一行就能「映射」数组
js
const map = new Map(arr.map(item => [item.id, item.value]));
这是不是比用 reduce + object 拼键值对方便多了?
为什么我们以前不用 Map?
我相信有部分人一定和我一样,不用new Map完全是因为不了解这个东西,也不知道它的使用场景!没关系,我来帮你梳理一下。
常用方法
方法 | 作用 |
---|---|
set(key, value) |
添加/更新键值对 |
get(key) |
获取值 |
has(key) |
判断是否存在 |
delete(key) |
删除键 |
clear() |
清空所有项 |
size |
获取长度 |
keys() / values() / entries() |
遍历器方法 |
[...map] / Array.from(map) |
转成数组 |
- 创建一个 Map
js
const map = new Map();
也可以通过数组初始化:
js
const map = new Map([
['name', 'Alice'],
['age', 25]
]);
set(key, value)
添加或更新键值对。
js
map.set('city', 'Beijing');
map.set(123, 'number key');
map.set({ id: 1 }, 'object key');
返回值仍是该 Map
对象,可以链式调用:
c
map.set('a', 1).set('b', 2);
get(key)
获取对应键的值,找不到返回 undefined
。
js
map.get('city'); // "Beijing"
map.get('unknown'); // undefined
has(key)
判断是否存在某个键:
js
map.has('city'); // true
map.has('unknown'); // false
delete(key)
删除指定键值对:
js
map.delete('city'); // true
map.has('city'); // false
clear()
清空所有键值对:
js
map.clear();
map.size; // 0
size
返回当前 Map
的元素数量(只读):
js
const m = new Map();
m.set('x', 10);
m.set('y', 20);
console.log(m.size); // 2
遍历方法
keys()
返回一个可迭代对象,包含所有键:
js
for (let key of map.keys()) {
console.log(key);
}
values()
返回所有值:
js
for (let value of map.values()) {
console.log(value);
}
entries()
返回所有 [key, value]
对:
js
for (let [key, value] of map.entries()) {
console.log(key, value);
}
Map
本身也是可迭代对象,等价于 entries()
:
js
for (let [k, v] of map) {
console.log(k, v);
}
forEach(callback[, thisArg])
与数组类似,支持 forEach
:
js
map.forEach((value, key) => {
console.log(key, value);
});
转换为数组
使用扩展运算符:
js
const arr = [...map]; // [[key, value], ...]
仅键数组:
js
const keys = [...map.keys()];
值数组:
js
const values = Array.from(map.values());
实用场景
- 去重,但保留顺序
js
const map = new Map();
arr.forEach(item => map.set(item.id, item));
const result = [...map.values()];
- 根据对象某字段快速查找
js
const userMap = new Map(users.map(u => [u.id, u]));
const user = userMap.get(101);
是不是比用 find()
好用很多?
- 用作缓存池
js
const cache = new Map();
function fetchData(id) {
if (cache.has(id)) return cache.get(id);
const data = loadFromServer(id);
cache.set(id, data);
return data;
}
总结
不夸张地说,Map
就是更强大的对象升级版。所以嘛------你要是还没用 new Map()
,赶紧优雅起来吧😉