在之前的文章中曾经介绍过ES6的Map,并给出如何使用Map替换if-else语句的,但那篇文章中只是简单介绍。这篇文章会对判断语句的优化进行进一步的介绍。
if-else
let status = 0; if(status === 1) { //todo }else if(status === 2) { //todo }else if(status === 3) { //todo } ... else { //todo }
这个例子中,有多个if-else
分支用来判断多种status
的取值情况。
接着使用switch
对上面代码进行改造:
switch
let status = 0; switch (status) { case 1: //todo break; case 2: //todo break; case 3: //todo break; ... default: //todo break; }
可以发现,当需要判断的情况多了,if-else
和switch
差别并不大。尽管switch
在语句上更清晰了一些。
OK,我们继续优化:使用对象+一元条件运算符
的方式:
对象+ 一元条件运算符
let status = 1; const todoList = { '1': ['todo'], '2': ['todo'], '3': ['todo'], ... 'default': ['todo'] } let todo = todoList[status] || todoList['default']; //todo
这种方法将判断条件作为对象的属性名,将处理逻辑作为对象的属性值,通过对象属性名查找的方式进行逻辑处理。
但是,别停,还有其他方法:
Map
let status = 1; const todoList = new Map([ [1,['todo']], [2,['todo']], [3,['todo']], ['default',['todo']] ]) let todo = todoList.get(status) || todoList['default']; //todo
这里使用到ES6的Map对象,使用键值对
的方式进行条件匹配。但是,有人可能会问Map对象和前一个的Object对象有什么区别呢?
- 一个Object通常都有自己的原型,即’prototype’
- 一个Object的键只能是
字符串
或Symnols
,但一个Map的键可以是任意值。
- Map的键值对个数可以通过
Map.prototype.size
得到,而对象的键值对个数只能通过手动确认。
为了更加明显的突出Map的作用,我们再来看一个例子:
进一步介绍Map
let status = 0; let color = 'blue'; if(color === 'blue') { if(status === 1) { //todo }else if(status === 2) { //todo }else if(status === 3) { //todo }else { //todo } }else if(color === 'yellow') { if(status === 1) { //todo }else if(status === 2) { //todo }else if(status === 3) { //todo }else { //todo } }
这是一个二元判断,此时判断量就是加倍,代码也加倍。那么我们用Map来改造下:
let status = 0; let color = 'blue'; const todoList = new Map([ ['bule_1', ()=>{ //todo }], ['blue_2', ()=>{ //todo }], ['yellow_1', ()=>{ //todo }], ['yellow_2', ()=>{ //todo }], ['default_1', ()=>{ //todo }], ]) let todo = todoList.get(`${color}_${status}`) || todoList.get('default'); todo.call(this);
这时,我们把二元判断
的条件拼接成字符串,并用其为Map的键名。这种写法在多元条件判断时很好用。
当然,如果你觉得用字符串拼接有点变扭,你还可以这样:
const todoList = new Map([ [{color:'bule',status:1}, ()=>{ //todo }], [{color:'bule',status:2}, ()=>{ //todo }], [{color:'yellow',status:1}, ()=>{ //todo }], [{color:'yellow',status:2}, ()=>{ //todo }], ['default', ()=>{ //todo }], ])
这里我们使用了对象作为键名
。这就是Map比Object的有优点的地方
,即Map可以用任何类型的数据作为Key
。
进一步优化- 将处理逻辑缓存
const fnA = () => {} const fnB = () => {} const todoList = new Map([ [/^color_[1-3]$/,fnA], ['default', fnB], ]) let todo = [...todoList()].filter(([key,value])=>(key.test(`${color}_${status}`))) todo.forEach(([key,value])=>value.call(this))
这里,我们使用正则
作为Map的key
,符合正则的条件就会被执行。
总结
从上面的案例中,我们知道,判断可以从if-else
、switch
、Object
和Map
几种方式进行处理,Map不是绝对的,每种方式都有它适用的场景。