- 一个Object的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值,包括函数、对象、基本类型。
- Map 中的键值是有序的,而添加到对象中的键则不是。因此,当对它进行遍历时,Map 对象是按插入的顺序返回键值。
- 你可以通过 size 属性直接获取一个 Map 的键值对个数,而 Object 的键值对个数只能手动计算。
- Map 在涉及频繁增删键值对的场景下会有些性能优势。
map.set, map.get, fot ... of, forEach
<script>
let myMap=new Map();
myMap.set("a","test1");
myMap.set("a",1)
let obj={};
myMap.set(obj,"value_obj");
let function_test=function(){};
myMap.set("func",function_test);
console.log("getFunc:"+myMap.get(obj));
console.log("-------for of---------");
for(let [key,value] of myMap){
console.log(key+"="+value);
}
console.log("------------------");
for(let key of myMap.keys()){
console.log("key"+"="+key);
}
console.log("------------------");
for(let value of myMap.values()){
console.log("value"+"="+value);
}
console.log("-------forEach---------");
myMap.forEach(function(value,key){
console.log(key+"="+value);
});
</script>
Map的克隆
let mapClone=new Map(mapOrigin);
let mapOrigin=new Map([["key1","value1"],["key2","value2"]]);
let mapClone=new Map(mapOrigin);
mapClone.forEach(function(value,key){
console.log(key+"="+value);
});
console.log(mapOrigin===mapClone);//false
Map的合并
let mapMerge=new Map([...map1,...map2]); 注意操作符“...”是需要的。
<script>
let map1=new Map([["1","one"],["2","two"],["3","threeqq"]]);
let map2=new Map([["3","three"],["4","four"]]);
let mapMerge=new Map([...map1,...map2]);
mapMerge.forEach(function(value,key){
console.log(key+"="+value);
});
</script>
对比多元判断场景使用 Object 与 map
/**
* 按钮点击事件
* @param {number} status 活动状态:1开团进行中 2开团失败 3 开团成功 4 商品售罄 5 有库存未开团
* @param {string} identity 身份标识:guest客态 master主态
*/
const onButtonClick = (status,identity)=>{
if(identity == 'guest'){
if(status == 1){
//do sth
}else if(status == 2){
//do sth
}else if(status == 3){
//do sth
}else if(status == 4){
//do sth
}else if(status == 5){
//do sth
}else {
//do sth
}
}else if(identity == 'master') {
if(status == 1){
//do sth
}else if(status == 2){
//do sth
}else if(status == 3){
//do sth
}else if(status == 4){
//do sth
}else if(status == 5){
//do sth
}else {
//do sth
}
}
}
map处理
const actions = new Map([
['guest_1', ()=>{/*do sth*/}],
['guest_2', ()=>{/*do sth*/}],
['guest_3', ()=>{/*do sth*/}],
...
['default', ()=>{/*do sth*/}],
])
Object处理
const actions = {
'guest_1':()=>{/*do sth*/},
'guest_2':()=>{/*do sth*/},
//....
}
/**
* 按钮点击事件
* @param {string} identity 身份标识:guest客态 master主态
* @param {number} status 活动状态:1 开团进行中 2 开团失败 3 开团成功 4 商品售罄 5 有库存未开团
*/
const onButtonClick = (identity,status)=>{
let action = actions.get(`${identity}_${status}`) || actions.get('default')
action.call(this)
}
是用Map对象,以Object对象作为key:
const actions = new Map([
[{identity:'guest',status:1},()=>{/*do sth*/}],
[{identity:'guest',status:2},()=>{/*do sth*/}],
//...
])
const onButtonClick = (identity,status)=>{
let action = [...actions].filter(([key,value])=>(key.identity == identity && key.status == status))
action.forEach(([key,value])=>value.call(this))
}
假如判断条件变得特别复杂,比如identity有3种状态,status有10种状态,那你需要定义30条处理逻辑,而往往这些逻辑里面很多都是相同的,这似乎也是笔者不想接受的,那可以这样实现:
const actions = ()=>{
const functionA = ()=>{/*do sth*/}
const functionB = ()=>{/*do sth*/}
return new Map([
[/^guest_[1-4]$/,functionA],
[/^guest_5$/,functionB],
//...
])
}
const onButtonClick = (identity,status)=>{
let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`)))
action.forEach(([key,value])=>value.call(this))
}
这里Map的优势更加凸显,可以用正则类型作为key了,这样就有了无限可能,假如需求变成,凡是guest情况都要发送一个日志埋点,不同status情况也需要单独的逻辑处理,那我们可以这样写:
const actions = ()=>{
const functionA = ()=>{/*do sth*/}
const functionB = ()=>{/*do sth*/}
const functionC = ()=>{/*send log*/}
return new Map([
[/^guest_[1-4]$/,functionA],
[/^guest_5$/,functionB],
[/^guest_.*$/,functionC],
//...
])
}
const onButtonClick = (identity,status)=>{
let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`)))
action.forEach(([key,value])=>value.call(this))
}
也就是说利用数组循环的特性,符合正则条件的逻辑都会被执行,那就可以同时执行公共逻辑和单独逻辑,因为正则的存在,你可以打开想象力解锁更多的玩法,本文就不赘述了。笔记!