在js的编码过程中,条件判断可以说是非常常用。当判断条件过多或者逻辑比较复杂时,清晰的代码结构和编码思路显得尤为重要。
需求描述:页面列表-操作列-点击不同的操作按钮-做不同的事
下面介绍笔者在编码过程中,对条件判断语句代码的优化
if/else判断
if(params == 'EDIT' ){
//to do
}else if(params == 'VIEW'){
//to do
}else if(params == 'DEL'){
// to do
}
- 优点:简单、熟悉
- 缺点:条件过多时,代码臃肿,逻辑不够清晰;
总结:if/else是我们最熟悉且常用的结构,但是当判断分支过多时,十几个if/else影响你的心情的同时代码性能也收到了影响,对于代码后期的优化重构,也带来很大困难,这里就不赘述了,读者可自行脑补...。
switch/case判断
switch(params){
case 'EDIT':
//to do
break
case 'VIEW':
//to do
break
case 'DEL':
//to do
break
default
//to do
break
}
- 优点:相较于ifelse-性能高、逻辑清晰、结构简单
- 缺点:没有明显缺点
总结:switch结构在代码性能上比if/else结构访问效率高的同时,代码整体逻辑结构也显得更加清晰明了
Object对象参数
function handleClick(params){
let actions={
'EDIT':function(){},
'VIEW':function(){},
'DEL':function(){},
'default':function(){}
}
return (actions[params] ||actions[default])()
}
//将判断条件作为对象的属性名,将处理逻辑作为对象的属性值
- 优点:相较switch 结构优雅
- 缺点:对象结构只适用在字符串结构下-actions的属性名只能是字符串
es6 Set 和 Map 数据结构
js的对象(Object-键值对)传统意义上只能是字符串作为键,在特殊的场景下带来了很大限制; 如果将一个
DOM
节点作为键,直接就会被自动转为字符串[object HTMLDivElement]
,ES6提供的Map数据结构,就可以处理这种问题
//example:
const a =new Map();
const o = {params:'hi siri'};
a.set(o,'hello');
a.get(o)// hello
// main
function handleClick(params){
let actions = new Map([
['EDIT',function(){}],
['VIEW',function(){}],
['DEL',function(){}],
['default',function(){}]
])
return (actions.get(params)||actions.get('default'))()
}
到此似乎一起都已经结束了,有读者也许会发文,以上结构适用在一元判断没有问题,如果是二元判断、多元判断以上还能否适用尼?
答案是肯定能用,只是在结构和思路上有所调整
多元判断
处理思路:在actions中列出每个多元判断条件下,所执行的函数步骤,多个传参拼接成字符串,从actions中获取函数
需求描述:判断身份,再身份判别的基础上再执行不同类型的操作,这里以Mao结构举例,Object结构类似
/**
* identity manager:管理员;guest:客户
* status 1:下单;2:付款;3:取消订单
*/
let actions = new Map([
['manager_1',function(){}],
['manager_2',function(){}],
['manaber_3',function(){}],
['guest_1',function(){}],
['guest_3',function(){}],
['guest_3',function(){}],
['default',function(){}]
])
const handleClick=(manager,status)=>{
let action = actions.get[`${manager}_${status}`]||actions.get['default']
action.call(this)
}
如上需求描述,如果是客户身份,假如 1、2、3状态执行的方法都一致,又该当如何?
处理思路:缓存具有共性的函数
/**
* identity manager:管理员;guest:客户
* status 1:下单;2:付款;3:取消订单
*/
let fnA = function(){}
let fnB = function(){}
let actions = new Map([
['manager_1',function(){}],
['manager_2',function(){}],
['manaber_3',function(){}],
['guest_1',fnA],
['guest_2',fnA],
['guest_3',fnA],
['default',function(){}]
])
const handleClick=(manager,status)=>{
let action = actions.get[`${manager}_${status}`]||actions.get['default']
action.call(this)
}
如上需求描述,fnA函数重复调用了三次,逻辑优化又该当如何?
处理思路:正则判断参数,动态获取执行函数
/**
* identity manager:管理员;guest:客户
* status 1:下单;2:付款;3:取消订单
*/
const actions = ()=>{
const fnA = ()=>{}
const fnB = ()=>{}
return new Map([
[/^guest_[1-2]$/,fnA],
[/^guest_3$/,fnB],
//...
])
}
const handleClick = (identity,status)=>{
//map类型数据转数组循环
let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`)))
action.forEach(([key,value])=>value.call(this))
}
// 过滤出符合正则条件的逻辑函数,循环执行
此处不做过多介绍Map数据结构及方法,感兴趣的同学请参考阮一峰老师ECMAScript 6入门
彩蛋:
细心的读者可能会发现文中函数声明和调用方式也略有不同
- Object声明方式,立即执行函数调用
- 函数声明方式,正常调用
文后总结:
本文提供了7种判断逻辑结构
- if/else常用判断结构
- switch/case判断结构
- Object对象参数结构
- es6-map数据结构-
- 多元判断-常用结构
- 多元判断-函数缓存结构
- 多元判断-正则判断、动态返回结构
需求变化千千万,更多的编码思路值得我们去发掘,有兴趣的同学可以来补充。
本文所述内容,如有疑问请随时与笔者联系;如发现问题,欢迎随时指正。