专栏名称: 守候i
web前端开发
目录
相关文章推荐
51好读  ›  专栏  ›  守候i

[浅析] 特定场景下代替优化 if-else 的方案 (二)

守候i  · 掘金  · 前端  · 2020-07-06 00:36

正文

阅读 1279

[浅析] 特定场景下代替优化 if-else 的方案 (二)

有一再有二,有二再有三。把未知的变成已知,就成了自己的知识

前言

很久之前,发了一篇文章: [浅析]特定场景下取代if-else和switch的方案 ,但是关于使用 if-else 的场景可不会仅仅是上面文章那么少,还有很多的场景,今天再次写下在开发上有哪些可以代替或者优化 if-else 的场景。

这里强调代替或者优化 if-else ,是在特定场景下进行的。目的就是为了在特定场景下改善代码,让代码简洁。增加代码的可读性,维护性,复用性。如果 if-else 使用的场景比较简单,或者代替,优化 if-else 后会对代码产生不好的影响。就不建议使用别的方案代替或者优化,不能为了不写 if-else 而不写,不能为了优化而优化。

1.范围查询

比如抽取中奖的号码区间,中奖的号码区间分别是 9-12,14-18,然后需要判断号码是否中奖了,逻辑很简单就实现了

let num1= 15
let num2= 13
if((num1>=9 && num1<=12)||(num1>=14 && num1<=18)){
     // 中奖了
}
if((num2>=9 && num2<=12)||(num2>=14 && num2<=18)){
     // 中奖了
}
复制代码

这样写貌似没什么问题,如果以后需求变了,中奖的号码不是9-12或者14-18。而是 10-14 或者 18-20。这样就要改原来的代码逻辑

if((num1>=10 && num1<=14)||(num1>=18 && num1<=20)){
     // 中奖了
}
复制代码

或者又有其他需求,比如中奖号码是 9-12,14-18,20-22或者26-30。还是要改动一下 if-else 的逻辑

if((num1>=9 && num1<=12)||(num1>=14 && num<=18)||(num1>=20 && num1<=22)||(num2>=26 && num1<=30)){
     // 数字在范围内
}
复制代码

现在可以用some 进行封装一个函数,只需要一次封装,往后的需求如果范围区间改变了,就可以

function handleCheckRange(num, ...ranges){
    return ranges.some(item=>num>=item[0]&&num<=item[1])
}
handleCheckRange(num1,[9,12],[14,18]) //true
handleCheckRange(num2,[9,12],[14,18]) //false
handleCheckRange(num2,[10,14],[18,20]) //true
handleCheckRange(num2,[9,12],[14,18],[20,22],[26,30]) //false
复制代码

1.可能有人会想到如果再有需求,判断条件不是 >= 或者 <= 。可能是 < 和 >,<= 和 >,或者 < 和 >=呢?这样 handleCheckRange 也是需要改了。这种情况确实,遇到其他的判断条件是需要改一下这个方法。但是改一下这个方法并不难,直接封装就好

2.如果判断条件太多变化,一定要封装方法兼容其他的判断条件,可以参考我的笔记: 练习题5:模拟实现开闭区间 ,这里就不展开讲了。

2.多个与条件

相信大家都会遇到可能会有多个条件组合的问题

比如有一个参与热卖活动赠积分活动,活动状态( status ),预热中( status=1 ),进行中( status=2 )。用户类型( type )也有分普通用户( type=1 )vip用户( type=2

规则是: 1.在预热中参与活动,vip用户赠送 1000 积分,普通用户赠送 700 积分。 1.在进行中参与活动,vip用户赠送 800 积分,普通用户赠送 300 积分。

之前写法是

let status=1
let type=2
if(status===1){
     if(type===1){
           console.log('普通用户在预售中参与活动,赠送700积分')
    }
    else if(type===2){
           console.log('vip用户在预售中参与活动,赠送1000积分')
    }
}
else if(status===2){
     if(type===1){
           console.log('普通用户在进行中参与活动,赠送300积分')
    }
    else if(type===2){
           console.log('vip用户在进行中参与活动,赠送800积分')
    }
}

// 或者

if(status===1&&type===1){
    console.log('普通用户在预售中参与活动,赠送700积分')
}
else if(status===1&&type===2){
    console.log('vip用户在预售中参与活动,赠送1000积分')
}
else if(status===2&&type===1){
    console.log('普通用户在进行中参与活动,赠送300积分')
}
else if(status===2&&type===2){
    console.log('vip用户在进行中参与活动,赠送800积分')
}
复制代码

但是现在可以使用 obj写法,这样下来,如果以后有什么条件改了,直接改 obj 这个配置就好。

let obj={
   'status=1&type=1':'普通用户在预售中参与活动,赠送700积分',
   'status=1&type=2':'vip用户在预售中参与活动,赠送1000积分',
   'status=2&type=1':'普通用户在进行中参与活动,赠送300积分',
   'status=2&type=2':'普通用户在进行中参与活动,赠送800积分'
}

console.log(obj[`status=${status}&type=${type}`])
复制代码

3.多个或条件

比如输入一个城市名字,输出一个省份名称

let city='广州'
if(city==='广州'||city==='佛山'){
    console.log('广东')
}
else if(city==='海口'||city==='三亚'){
    console.log('海南')
}
复制代码

这样写的弊端就是,如果 if-else 数量一多,代码就会多,而且判断的条件会变得很长,还有一个问题就是风格有可能不会统一

下面用其他方法进行优化下 方法一

let arr=[
    {
        city:'广州',
        province:'广东'
    },
    {
        city:'佛山',
        province:'广东'
    },
    {
        city:'海口',
        province:'海南'
    },
    {
        city:'三亚',
        province:'海南'
    }
]
console.log(arr.filter(item=>item.city===city)[0].province)//广东
复制代码

方法二

let city='广州'
let obj={
    '广州':'广东',
    '佛山':'广东',
    '海口':'海南',
    '三亚':'海南',
}
console.log(obj[city])// 广东
复制代码

见到 广东 和 海南 写了这么多次,可能大家都会郁闷,一个省城市有 20 个,就要写 20 次,可能就有人会想到把城市都作为 key ,然后判断传进来的 city 是否在 key 里面,代码如下。

let city='广州'
let obj={
    '广州,佛山':'广东',
    '海口,三亚':'海南',
}
for(let key in obj){
    if(key.includes(city)){
        console.log(obj[key])
        break
    }
}
//广东

复制代码

但是弊端也出来了,就是上面的方法有 bug ,只输出城市名称的其中一个字,也能输出对应的省份。

let city='州'
let obj={
    '广州,佛山':'广东',
    '海口,三亚':'海南',
}
for(let key in obj){
    if(key.includes(city)){
        console.log(obj[key])
        break






请到「今天看啥」查看全文