特定场景下代替优化 if-else 的方案,好用

// 1、多个与条件
    // 相信大家都会遇到可能会有多个条件组合的问题
    // 比如有一个参与热卖活动赠积分活动,活动状态(status),预热中(status=1),进行中(status=2)。用户类型(type)也有分普通用户(type=1)vip用户(type=2)
    // 规则是:
    // 1.在预热中参与活动,vip用户赠送 1000 积分,普通用户赠送 700 积分。
    // 1.在进行中参与活动,vip用户赠送 800 积分,普通用户赠送 300 积分。
    // 之前写法
    // 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积分')
    // }
    // 优化写法:
    var status = 1
    var type = 2
    var 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])

    // 2、范围查询
    // 比如抽取中奖的号码区间,中奖的号码区间分别是 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)) {
        // 中奖了
    }
    // 现在可以用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

    // 3、多重if
    // 还有一种情况是,几个 if-else 连着执行的代码,
    // 比如有一个页面,能显示用户记录的足迹,也可以让用户选择记录自己的足迹,记录的范围可以是省,是市,是区。那么代码就需要实现一个省市区,多选联动。逻辑就是选了省,未必会选择市,但是选了市就必然会选了省,以此类推。下面简单写一下伪代码。  
    function initPostion() {
        //所有省份列表
        let provinceList = ['广东', '广西', '海南', '....']
        //已选省份下辖的所有城市
        let cityList = []
        //已选城市下辖的所有区
        let districtList = []

        //已选择省份
        let selectedProvinces = ['广东', '广西']
        //已选择城市
        let selectedCitys = ['广州']
        //已选择区
        let selectedDistricts = ['天河区']

        //如果选了省份
        if (selectedProvinces.length > 0) {
            //根据 selectedProvinces 获取 cityList 的逻辑
            //其他代码
        }
        if (selectedCitys.length > 0) {
            //根据 selectedCitys 获取 districtList 的逻辑
            //其他代码
        }
        //其他初始化显示的逻辑
    }
    //伪代码一写,想必有开发者已经看出问题了。所有的 if 都耦合在一起了, 而且 if 里面的代码逻辑可能会很多长。如果以后需求改了,要求选了国家,再选省市区,或者选择区之后,还能选择镇和村。到时候 if 会变多,initPostion 整体代码会变得巨大。维护起来会比较吃力,同时也容易出错。
    // 解决这问题,可以把 if 拆分为函数。
    function initPostion() {
        //所有省份列表
        let provinceList = ['广东', '广西', '海南', '....']
        //已选省份下辖的所有城市
        let cityList = []
        //已选城市下辖的所有区
        let districtList = []

        //已选择省份
        let selectedProvinces = ['广东', '广西']
        //已选择城市
        let selectedCitys = ['广州']
        //已选择区
        let selectedDistricts = ['天河区']

        let handleObj = {
            provinces() {
                //如果选了省份
                if (selectedProvinces.length > 0) {
                    //根据 selectedProvinces 获取 cityList 的逻辑
                    //其他代码
                }
            },
            city() {
                if (selectedCitys.length > 0) {
                    //根据 selectedCitys 获取 districtList 的逻辑
                    //其他代码
                }
            }
        }

        let handleFns = ['provinces', 'city']

        for (let fnName of handleFns) {
            handleObj[fnName]()
        }

        //其他初始化显示的逻辑
    }
    // 可能这样看着代码是多了,但是管理起来会比原来的方案容易管理,每一块 if 都被拆分为一个函数,如果需要改动某一块代码,就改某一块就行了,不需要对其他的代码进行改动。如果有需求上的变动,就是改 handleObj 的属性函数,以及 handleFns 的顺序就行了。

// 作者:守候i
// 链接:https://juejin.im/post/5efc55496fb9a07e9a079a5e
// 来源:掘金
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
// https://juejin.im/post/5efc55496fb9a07e9a079a5e

 

posted @ 2020-07-08 10:52  问问大将军  阅读(220)  评论(0编辑  收藏  举报