ES6的Map 对比 Object

207 阅读3分钟
  • 一个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))
}

也就是说利用数组循环的特性,符合正则条件的逻辑都会被执行,那就可以同时执行公共逻辑和单独逻辑,因为正则的存在,你可以打开想象力解锁更多的玩法,本文就不赘述了。笔记!

本文转自 juejin.cn/post/684490…