啥时候应当使用ES6 Map?
你可能问,都2021年了,咋还在讨论Map基础?这不是Vue 3.0来了么,2021年就可以上生产了,Vue 2.0可以遍历Map,但是不支持响应式,现在3.0支持Map的响应式了,你说要不要开始学呢?
废话不说,跟Object做个对比。
Map优势方面
Map | Object | |
---|---|---|
key类型 | 任意类型 | String 或 Symbol |
长度 | .size直接得出 | 遍历或Object.keys().length得出 |
频繁增删键值对 | 性能好 | 性能差 |
属性纯净度 | 纯净 | 可能与原型链上的属性冲突 |
支持forEach循环或for...of...循环 | 支持 | 不支持 |
属性排序 | 按插入顺序 | 不确定的顺序 |
Map劣势方面
Map | Object | |
---|---|---|
可被JSON.stringify处理 | 不能 | 能 |
适用于前后端数据传递 | 由于不被JSON支持,所以不适合 | 适合 |
Map无所谓优劣方面
Map | Object | |
---|---|---|
直接量写法 | 构造函数传入二维数组 | 直接写键值对 |
总结
当需要使用除 String 和 Symbol 以外的键名时,那么Map是最佳解决方案。
如果需要按插入顺序遍历键值对,用Map。
频繁增删改查,用Map。
想用更方便的原生方法操作,用Map。
用于设计模式。我们经常遇到N个if...else...,这时候就需要考虑设计模式,由于正则表达式可以作为Map的key,所以可以准备一堆键值对,来判断一个字符串是否符合正则表达式,通常用于表单验证,可以写起来更优雅。
关于Map用于前后端数据交互
Map由于不被JSON支持,所以不适合前后端数据交互,即便是前端加工后端数据,也不值得专门把对象转为Map,毕竟数据都非常简单,只有在特定业务需要的前提下,才会有对象转Map的必要,因此,应当把Map用在前后端数据交互以外的其他某些场合。
Map的原生属性
- size,获取长度
Map的操作方法
.set(key, value):返回整个Map结构。如果key已经有值,则键值会被更新,否则就新生成该键。由于返回整个Map,所以可以链式操作。
.get(key):获取不到则返回undefined。
.has(key):键是否在Map中,返回布尔值。
.delete(key):删除成功返回true,失败返回false。
.clear():Map会成为空Map,方法执行返回undefined。
Map的遍历方法
.keys():返回键名的遍历器(即MapIterator)。不支持
.forEach
,支持...
。.values():返回键值的遍历器(即MapIterator)。不支持
.forEach
,支持...
。.entries():返回所有成员的遍历器(即MapIterator)。通常没用,遍历Map本身可以使用
.forEach
,遍历它的遍历器反而不能用.forEach
,也就是说这个遍历器更弱。.forEach():遍历 Map 的所有成员。跟数组完全一致的用法。
Map如何使用数组的原生方法?
基本原则就是先利用解构得到二维数组。
Map、对象、数组最优雅互转
- Map转对象
没什么优雅的方法,只能是遍历Map,然后依次给对象附加属性。
const map = new Map();
map.set(1,"foo").set(2,"bar").set(3,"baz");
const mapToObj = (map) => {
let obj = {};
for(let [k,v] of map) {
obj[k] = v;
}
return obj;
}
console.log(mapToObj(map));
- Map转数组
最优雅办法是解构,这种方法会得到二维数组,每个元素格式类似[1, 'foo']
。如果只想得到键或者值组成的数组,需要改成...map.map(v=>v[0])
或者...map.map(v=>v[1])
。
const map = new Map();
map.set(1,"foo").set(2,"bar").set(3,"baz");
const arr = [...map];
console.log(arr);
- 对象转Map
优雅办法是使用Object.entries()将对象解构,得到的结果也是二维数组,跟...
将可遍历对象解构的结果是一样的。恰好new Map()接受二维数组转换为Map。
let obj = {"a":1, "b":2};
let map = new Map(Object.entries(obj));
- 数组转Map
上面已经说过,符合格式的二维数组可以直接转换为Map,如果是一维数组转Map呢?首先这不一定有必要,因为可能一维数组转Set更好一些,如果一定要转Map,可以这样:
const arr = ["foo","bar","baz"];
const arrToMap = (arr) => new Map(arr.map( (value,key) => [key,value]));
console.log(arrToMap(arr));
作者:microkof
原文链接:https://www.jianshu.com/p/5ee24c489ed5