如何对多个if |
您所在的位置:网站首页 › 满足多个条件的if函数是什么 › 如何对多个if |
如何对多个if-else判断进行优化
当我们遇到需要多个条件判断的业务操作时,最简单直接的办法就是用多个if-else判断,虽然能够实现,但当判断条件过多,甚至是多元判断时,我们的代码就会变得非常不好阅读和维护。 举个例子这里也可以用switch if(status === '1'){ return '未审批' }else if(status === '2'){ return '审批中' }else if(status === '3'){ return '审批通过' }else if(status === '4'){ return '审批退回' }else if(status === '5'){ return '审批异常' }当判断越来越多的时候,优化的空间就来了,接下来和大家分享几种不同场景下关于if-else判断的优化技巧。 1、使用Object对象 适用于单层多个判断 这是一种比较常见的方式,用Object对象把判断收集到一起 const statusArr = { '1': '未审批', '2': '审批中', '3': '审批通过', '4': '审批退回', '5': '审批异常' } function getStatus(Num) { return statusArr[Num] } getStatus('1') //未审批这样是不是变得优雅一些了呢?可能看下来可能优化的效果没有非常显著,但别忘了,开发时也许不同的状态对应的是一个不同的方法,如果直接写在if-else中,代码就会变得又臭又长,举个例子对比一下 代码仅作举例,没有实际意义 if(status === '1'){ //一些操作 status = '2' return '未审批' }else if(status === '2'){ //一些操作 status = '3' return '审批中' }else if(status === '3'){ //一些操作 status = '4' return '审批通过' }else if(status === '4'){ //一些操作 status = '5' return '审批退回' }else if(status === '5'){ //一些操作 status = '0' return '审批异常' }怎么样,是不是已经眼花撩乱。同样优雅一下 const statusArr = { '1': ()=>{ //一些操作 status = '2' return '未审批' }, '2': ()=>{ //一些操作 status = '3' return '审批中' }, '3': ()=>{ //一些操作 status = '4' return '审批通过' }, '4': ()=>{ //一些操作 status = '5' return '审批退回' }, '5': ()=>{ //一些操作 status = '0' return '审批异常' }, } function getStatus(Num) { return statusArr[Num] } getStatus('1')()这样的话,将逻辑通过数据的形式维护起来,可读性更好。 以上的方式也可以使用Map对象,相比于Object,Map对象的键就不仅仅只能是一个字符串,可以是任意值,包括函数、对象、基本类型,更加灵活。 实际情况不多,不做举例。 对于Map对象不了解的可以通过这篇博文简单了解。链接: Map对象的使用. 2、通过字符串拼接的方式 和上一种方式道理是一样,拼接后适合多元判断,例如不同的角色,通过字符串拼接的方式,在对象,或Map对象中进行查找相应的逻辑。 举个例子:(比如当我们加上一个角色判断时) if(role === '打工人') { if(status === '1'){ //一些操作 }else if(status === '2'){ //一些操作 }else if(status === '3'){ //一些操作 }else if(status === '4'){ //一些操作 }else if(status === '5'){ //一些操作 } } else if(role === '老板娘') { if(status === '1'){ //一些操作 }else if(status === '2'){ //一些操作 }else if(status === '3'){ //一些操作 }else if(status === '4'){ //一些操作 }else if(status === '5'){ //一些操作 } }可以看到,当同一个方法,不同角色不同状态执行的操作不同时,代码将会变得冗长。 优化的方法:同样使用一个对象收集这种不同的状态,但是由于多元的关系,将角色和状态进行字符串的拼接。 let statusArr = { '打工人_1': ()=>{ \\一些操作 }, '打工人_2': ()=>{ \\一些操作 }, '打工人_3': ()=>{ \\一些操作 }, '打工人_4': ()=>{ \\一些操作 }, '打工人_5': ()=>{ \\一些操作 }, '老板娘_1': ()=>{ \\一些操作 }, '老板娘_2': ()=>{ \\一些操作 }, '老板娘_3': ()=>{ \\一些操作 }, '老板娘_4': ()=>{ \\一些操作 }, '老板娘_5': ()=>{ \\一些操作 }, } function getStatus(role,status) { return statusArr[`${role}_${status}`] }可以看到,改造之后,更加简明易读, 不过个人认为这种拼接的方式始终不够规范,易读很可能只针对自己,对于接手的可能语义化还不够,下面介绍一种更好的方式。 3、使用对象的方式存放在Map对象上 上面这种方式之所以要拼接在一起,是因为对象的键需要是字符串的限制,如果使用Map对象,键就可以是一个对象、数组或者更多类型,方便了很多。 let statusMap = new Map([ [{role: '打工人', status : '1'}, ()=>{ /*一些操作*/ }], [{role: '打工人', status : '2'}, ()=>{ /*一些操作*/ }], [{role: '打工人', status : '3'}, ()=>{ /*一些操作*/ }], [{role: '打工人', status : '4'}, ()=>{ /*一些操作*/ }], [{role: '打工人', status : '5'}, ()=>{ /*一些操作*/ }], [{role: '老板娘', status : '1'}, ()=>{ /*一些操作*/ }], [{role: '老板娘', status : '2'}, ()=>{ /*一些操作*/ }], [{role: '老板娘', status : '3'}, ()=>{ /*一些操作*/ }], [{role: '老板娘', status : '4'}, ()=>{ /*一些操作*/ }], [{role: '老板娘', status : '5'}, ()=>{ /*一些操作*/ }], ]) let getStatus = function(role,status) { statusMap.forEach((value,key)=>{ if(JSON.stringify(key) == JSON.stringify({role: role,status: status})){ value() } }) } getStatus('打工人','1') // 一些操作解释一下这段代码: 将状态和角色组成对象放入Map对象中作为键名,将不同的方法作为对应的值。 getStatus方法找到对应的操作并执行 这里有一个小坑,由于键名是对象,所以查找Map对象时不能用Map.get()的方法,原因是由于对象的引用类型的问题,所以我用了这种方式转成字符串来比较。实测没有问题。 以上几种都是基于处理逻辑和配置数据分离的优化方法,这种方法适用于一些不是逻辑不是太复杂的处理。 对于一些复杂的处理逻辑,可以考虑使用责任链模式,这里简单介绍一下这种设计模式。 4、责任链模式 以上的几种方式,都是用穷举的方式在配置数据中查找到相对应的处理方法,而责任链模式就是将整个处理的逻辑改写成一条责任传递链,请求在这条链上传递,直到有一个对象处理这个请求。 举个例子: 在一个购物商城,在五一做了一个活动,所以图书类商品根据购买的金额依次做出以下折扣方案 1、购买满199元,打9折 2、购买满399元,打8折 3、购买满599元以上,打7折; 同样,用最简单的if-else判断写一下 if(price return '9折' }else if(399 return '7折' }这里看起来并没有很复杂,但是如果在实际业务中,并不仅仅只需要返回一个折扣力度,可能还需要对活动商品、活动库存、是否使用优惠券等等进行计算,这样的话我们所有的逻辑就全部都写在这一个方法内的if判断语句内,可以想象,可读性是很差的。 用责任链模式示范一下: 第一个节点,原价的处理 function BookHandler() { this.calcPrice = function( price ) { if ( 199 > price ) { console.log("原价是:"+ price); } else { this.successor.calcPrice( price ); } } this.setSuccessor = function( _successor ) { this.successor = _successor; } } 第二个节点,9折的处理 function BookCalc9Handler( _successor ) { this.calcPrice = function( price ) { if ( 199 this.successor.calcPrice( price ); } } this.setSuccessor = function( _successor ) { this.successor = _successor; } } 第三个节点,8折的处理 function BookCalc8Handler() { this.calcPrice = function( price ) { if ( 399 this.successor.calcPrice( price ) } } this.setSuccessor = function( _successor ) { this.successor = _successor; } } 最后,7折的处理 function BookCalc7Handler() { this.calcPrice = function( price ) { if ( price >= 599 ) { console.log("原价是:"+ price +";打7折后:" + (price * 0.7)); } else { this.successor.calcPrice( price ) } } this.setSuccessor = function( _successor ) { this.successor = _successor; } }调用时: var price = 400; var bookHandler = new BookHandler(); var bookCalc9Handler = new BookCalc9Handler(); var bookCalc8Handler = new BookCalc8Handler(); var bookCalc7Handler = new BookCalc7Handler(); bookHandler.setSuccessor(bookCalc9Handler); bookCalc9Handler.setSuccessor(bookCalc8Handler); bookCalc8Handler.setSuccessor(bookCalc7Handler); 将所有处理方法连成一条责任链,保证总有一个对象能够处理请求 bookHandler.calcPrice(price);console.log的结果 如果不使用责任链链模式、根据当前价格要知道每一级打折信息,最后知道具体是那一层上打折才是符合当前价格的折扣。而使用这种模式,只需要知道当前的处理对象是否能够处理,如果不能处理,就传递给下一个对象,直到有一个对象最终处理,逻辑性更强。 小结事实上,大部分业务需求都能使用最基本的if-else完成,只不过是简单和繁琐的问题,当我们遇到这类问题,不妨改变一下思路,将自己的代码优雅化,使用上数据配置或责任链模式,你会发现不仅仅是思路的扩展,代码的逻辑都清晰了不少,希望对各位有所帮助。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |