Home  >  Article  >  Web Front-end  >  Eliminate if else and make your code look more elegant

Eliminate if else and make your code look more elegant

coldplay.xixi
coldplay.xixiforward
2020-10-12 17:51:372548browse

javascriptThe column introduces how to eliminate if else and make your code look more elegant. Let’s take a look.

Eliminate if else and make your code look more elegant

##Preface

There should be many students who have encountered this I have seen code that is full of if else. Faced with such a mess, simply and crudely continuing to make incremental modifications will often only make the complexity higher and higher and the readability worse and worse. Then it’s time to refactor, take a few minutes to read this article, maybe it will be helpful to you.


Scenario 1: Display the corresponding name according to status

Optimization plan 1: object object

const statusStr = {
  '1': '待付款',
  '2': '待发货',
  '3': '已发货',
  '4': '交易完成',
  '5': '交易关闭',
  'default': '',
}
const getStatus = (status) =>{
  return statusStr[status] || statusStr['default']
}

will judge The condition is used as the attribute name of the object, and the processing logic is used as the attribute value of the object. When the button is clicked, logical judgment is made by searching the object attributes.

Optimization plan 2: Map object

const statusStr = new map([
  '1': ['待付款'],
  '2': ['待发货'],
  '3': ['已发货'],
  '4': ['交易完成'],
  '5': ['交易关闭'],
  'default': [''],
])
const getStatus = (status) =>{
  let actions = statusStr.get(status) || statusStr.get('default')
  return  actions[0];
}

This writing uses the Map object in es6, so what is the difference between the Map object and the Object object?

An object usually has its own prototype, so an object always has a "prototype" key. The keys of an object can only be strings or Symbols, but the keys of a Map can be any value. You can easily get the number of key-value pairs in a Map through the size attribute, while the number of key-value pairs in an object can only be confirmed manually.

Scenario 2: Multiple condition corresponding names

Now let’s upgrade the problem. In the past, when clicking the button, you only needed to judge the status, but now you still need to Determine the user's identity:

「For example:」

const onButtonClick = (status,identity)=>{
  if(identity == 'guest'){
    if(status == 1){
      //do sth
    }else if(status == 2){
      //do sth
    }else if(status == 3){
      //do sth
    }else if(status == 4){
      //do sth
    }else if(status == 5){
      //do sth
    }else {
      //do sth
    }
  }else if(identity == 'master') {
    if(status == 1){
      //do sth
    }else if(status == 2){
      //do sth
    }else if(status == 3){
      //do sth
    }else if(status == 4){
      //do sth
    }else if(status == 5){
      //do sth
    }else {
      //do sth
    }
  }
}

We can see from the above example that when your logic is upgraded to binary judgment, your judgment amount will double, and your code The volume will also double. How can we write more clearly at this time?

Optimization plan 1: Store the condition in the Map object in the form of character splicing

const actions = new Map([
  ['guest_1', ()=>{/*do sth*/}],
  ['guest_2', ()=>{/*do sth*/}],
  ['guest_3', ()=>{/*do sth*/}],
  ['guest_4', ()=>{/*do sth*/}],
  ['guest_5', ()=>{/*do sth*/}],
  ['master_1', ()=>{/*do sth*/}],
  ['master_2', ()=>{/*do sth*/}],
  ['master_3', ()=>{/*do sth*/}],
  ['master_4', ()=>{/*do sth*/}],
  ['master_5', ()=>{/*do sth*/}],
  ['default', ()=>{/*do sth*/}],
])
const onButtonClick = (identity,status)=>{
  let action = actions.get(`${identity}_${status}`) || actions.get('default')
  action.call(this)
}

The core logic of the above code is: splice the two conditions into a string, and pass Search and execute the Map object using conditional concatenation strings as keys and processing functions as values. This writing method is especially useful when judging multiple conditions.

Optimization plan 2: Store the condition in the Object object in the form of character splicing

const actions = {
  'guest_1':()=>{/*do sth*/},
  'guest_2':()=>{/*do sth*/},
  //....
}
const onButtonClick = (identity,status)=>{
  let action = actions[`${identity}_${status}`] || actions['default']
  action.call(this)
}

Optimization plan 3: Store the condition in the Map object in the form of an Object object

It may be a bit awkward to spell the query conditions into a string. There is another solution, which is to use a Map object and use the Object object as the key:

const actions = new Map([
  [{identity:'guest',status:1},()=>{/*do sth*/}],
  [{identity:'guest',status:2},()=>{/*do sth*/}],
  //...
])
const onButtonClick = (identity,status)=>{
  let action = [...actions].filter(([key,value])=>(key.identity == identity && key.status == status))
  action.forEach(([key,value])=>value.call(this))
}

Scenario 3: Make corresponding operations based on status

「Give me an example:」

function init () {
    if (isAnswer === 1) {
        if (isOldUser === 1) {
            // ...
        } else if (isOldUser === 2) {
            // ...
        }
    } else if (isAnswer === 2) {
        if (isOldUser === 1) {
            // ...
        } else if (isOldUser === 2) {
            // ...
        }
    } else if (isAnswer === 3) {
        if (isOldUser === 1) {
            // ...
        } else if (isOldUser === 2) {
            // ...
        }
    }
}

Optimization plan 1: Lookup table, chain of responsibility lookup table

const rules = [
    {
        match (an, old) {if (an === 1) {return true}},
        action (an, old) {
        if (old === 1) {// ...} 
        else if (old === 2) {// ...}
        }
    },
    {
        match (an, old) { if (an === 2) {return true } },
        action (an, old) {
            if (old === 1) {// ...} 
            else if (old === 2) {// ...}
        }
    },
    {
        match (an, old) {if (an === 3) {return true}},
        action (an, old) {
            if (old === 1) {// ...} 
            else if (old === 2) {// ...}
        }
    }
]
function init (an, old) {
    for (let i = 0; i < rules.length; i++) {
        // 如果返回true
        if (rules[i].match(an, old)) {
            rules[i].action(an, old)
        }
    }
}
init(isAnswer, isOldUser)

Although it may seem to be treating the symptoms rather than the root cause, it is not the case. The complexity of the init function is greatly reduced. We have split the complex logic of the control process into the determineAction function

Optimization plan 2: Functional programming

import R from &#39;ramda&#39;
var fn = R.cond([
  [R.equals(0),   R.always(&#39;water freezes at 0°C&#39;)],
  [R.equals(100), R.always(&#39;water boils at 100°C&#39;)],
  [R.T,           temp => &#39;nothing special happens at &#39; + temp + &#39;°C&#39;]
]);
fn(0); //=> &#39;water freezes at 0°C&#39;
fn(50); //=> &#39;nothing special happens at 50°C&#39;
fn(100); //=> &#39;water boils at 100°C&#39;

Scenario 4: Perform different processing according to the scope

"For example:" For example, you may encounter needs similar to the following: For example, the credit score rating of a certain platform, if it exceeds 700-950, it is credit Excellent, 650-700 has excellent credit, 600-650 has good credit, 550-600 has medium credit, and 350-550 has poor credit.

function showGrace(grace) {
    let _level=&#39;&#39;;
    if(grace>=700){
        _level=&#39;信用极好&#39;
    }
    else if(grace>=650){
        _level=&#39;信用优秀&#39;
    }
    else if(grace>=600){
        _level=&#39;信用良好&#39;
    }
    else if(grace>=550){
        _level=&#39;信用中等&#39;
    }
    else{
        _level=&#39;信用较差&#39;
    }
    return _level;
}

Optimization plan 1: Use look-up tables to separate configuration data and business logic

function showGrace(grace,level,levelForGrace) {
    for(let i=0;i<level.length;i++){
        if(grace>=level[i]){
            return levelForGrace[i];
        }
    }
    //如果不存在,那么就是分数很低,返回最后一个
    return levelForGrace[levelForGrace.length-1];
}
let graceForLevel=[700,650,600,550];
let levelText=[&#39;信用极好&#39;,&#39;信用优秀&#39;,&#39;信用良好&#39;,&#39;信用中等&#39;,&#39;信用较差&#39;];

Summary

In many cases we can use more flexible methods to replace if else and switch, but not all if else needs to be replaced, depending on the situation.

More related free learning: javascript(Video)

The above is the detailed content of Eliminate if else and make your code look more elegant. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.im. If there is any infringement, please contact admin@php.cn delete