深圳幻海软件技术有限公司 欢迎您!

这些优化技巧可以避免我们在 JS 中过多的使用 IF 语句

2023-02-27

最近在重构代码时,我发现早期的代码使用太多的if语句,其程度是我从未见过的。这就是为什么我认为分享这些简单的技巧是非常重要的,这些技巧可以帮助我们避免过多的使用if语句。接下来会介绍6种方式来代替if的使用,这样做不是坚决不使用if偏执狂,而是换个方式思考我们的编码思路。1.三元运算符(1)事例1带

最近在重构代码时,我发现早期的代码使用太多的 if 语句,其程度是我从未见过的。这就是为什么我认为分享这些简单的技巧是非常重要的,这些技巧可以帮助我们避免过多的使用 if 语句。

接下来会介绍6种方式来代替 if 的使用,这样做不是坚决不使用 if 偏执狂,而是换个方式思考我们的编码思路。

1. 三元运算符

(1) 事例1

带有IF的代码:

function saveCustomer(customer) { 
  if (isCustomerValid(customer)) { 
    database.save(customer) 
  } else { 
    alert('customer is invalid') 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

重构后代码:

function saveCustomer(customer) { 
  return isCustomerValid(customer) 
    ? database.save(customer) 
    : alert('customer is invalid') 
}  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

使用 ES6

const saveCustomer = customer => 
   isCustomerValid(customer)? 
     database.save(customer) : alert('customer is invalid')     
  • 1.
  • 2.
  • 3.

(2) 事例2

带有IF的代码:

 function customerValidation(customer) { 
   if (!customer.email) { 
     return error('email is require') 
   } else if (!customer.login) { 
    return error('login is required') 
   } else if (!customer.name) { 
     return error('name is required') 
   } else { 
     return customer 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

重构后代码:

const customercustomerValidation = customer => 
  !customer.email   ? error('email is required') 
  : !customer.login ? error('login is required') 
  : !customer.name  ? error('name is required') 
                    : customer 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

(3) 事例3

带有IF的代码:

 function getEventTarget(evt) { 
     if (!evt) { 
         evt = window.event; 
     } 
     if (!evt) { 
         return; 
     } 
     const target; 
     if (evt.target) { 
        target = evt.target; 
    } else { 
        target = evt.srcElement; 
    } 
    return target; 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

重构后代码:

function getEventTarget(evt) { 
  evtevt = evt || window.event; 
  return evt && (evt.target || evt.srcElement); 

  • 1.
  • 2.
  • 3.
  • 4.

2. 短路运算符

(1) 事例1

带有IF的代码:

 const isOnline = true
 const makeReservation= ()=>{}; 
 const user = { 
     name:'Damian', 
     age:32, 
     dni:33295000 
 }; 
  
 if (isOnline){ 
    makeReservation(user); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

重构后代码:

const isOnline = true
const makeReservation= ()=>{}; 
const user = { 
    name:'Damian', 
    age:32, 
    dni:33295000 
}; 
 
isOnline&&makeReservation(user); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

(2) 事例2

带有IF的代码:

 const active = true
 const loan = { 
     uuid:123456, 
     ammount:10, 
     requestedBy:'rick' 
 }; 
  
 const sendMoney = ()=>{}; 
  
if (active&&loan){ 
    sendMoney(); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

重构后代码:

const active = true
const loan = { 
    uuid:123456, 
    ammount:10, 
    requestedBy:'rick' 
}; 
 
const sendMoney = ()=>{}; 
 
ctive && loan && sendMoney(); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

3. 函数委托

事例1

带有IF的代码:

function itemDropped(item, location) { 
    if (!item) { 
        return false; 
    } else if (outOfBounds(location) { 
        var error = outOfBounds
        server.notify(item, error); 
        items.resetAll(); 
        return false; 
    } else { 
       animateCanvas(); 
       server.notify(item, location); 
       return true; 
   } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

重构后代码:

 function itemDropped(item, location) { 
     const dropOut = function() { 
         server.notify(item, outOfBounds); 
        items.resetAll(); 
         return false; 
     } 
 
     const dropIn = function() { 
         server.notify(item, location); 
        animateCanvas(); 
        return true; 
    } 
 
    return !!item && (outOfBounds(location) ? dropOut() : dropIn()); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

4. 非分支策略

此技巧尝试避免使用switch语句,相反是用键/值创建一个映射并使用一个函数访问作为参数传递的键的值。

(1) 事例1

带有switch的代码:

 switch(breed){ 
     case 'border': 
       return 'Border Collies are good boys and girls.'; 
       break;   
     case 'pitbull': 
       return 'Pit Bulls are good boys and girls.'; 
       break;   
     case 'german': 
       return 'German Shepherds are good boys and girls.'; 
      break; 
    default: 
      return 'Im default' 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

重构后代码:

const dogSwitch = (breed) =>({ 
  "border": "Border Collies are good boys and girls.", 
  "pitbull": "Pit Bulls are good boys and girls.", 
  "german": "German Shepherds are good boys and girls.",   
})[breed]||'Im the default'; 
 
 
dogSwitch("border xxx") 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

5. 作为数据的函数

我们知道在JS中函数是第一个类,所以使用它我们可以把代码分割成一个函数对象。

带有IF的代码:

 const calc = { 
     run: function(op, n1, n2) { 
         const result; 
         if (op == "add") { 
             result = n1 + n2; 
         } else if (op == "sub" ) { 
             result = n1 - n2; 
         } else if (op == "mult" ) { 
             result = n1 * n2; 
        } else if (op == "div" ) { 
            result = n1 / n2; 
        } 
        return result; 
    } 

 
calc.run("sub", 5, 3); //2 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

重构后代码:

 const calc = { 
     add : function(a,b) { 
         return a + b; 
     }, 
     sub : function(a,b) { 
         return a - b; 
     }, 
     mult : function(a,b) { 
         return a * b; 
    }, 
    div : function(a,b) { 
        return a / b; 
    }, 
    run: function(fn, a, b) { 
        return fn && fn(a,b); 
    } 

 
calc.run(calc.mult, 7, 4); //28 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

6. 多态性

多态性是对象具有多种形式的能力。OOP中多态性最常见的用法是使用父类引用来引用子类对象。

带有IF的代码:

 const bob = { 
   name:'Bob', 
   salary:1000, 
   job_type:'DEVELOPER' 
 }; 
  
 const mary = { 
   name:'Mary', 
   salary:1000, 
  job_type:'QA' 
}; 
 
const calc = (person) =>
 
    if (people.job_type==='DEVELOPER') 
        return person.salary+9000*0.10; 
 
    if (people.job_type==='QA') 
        return person.salary+1000*0.60; 

 
console.log('Salary',calc(bob)); 
console.log('Salary',calc(mary)); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

重构后代码:

 const qaSalary  = (base) => base+9000*0.10; 
 const devSalary = (base) => base+1000*0.60; 
  
 //Add function to the object. 
 const bob = { 
   name:'Bob', 
   salary:1000, 
   job_type:'DEVELOPER', 
   calc: devSalary 
}; 
 
const mary = { 
  name:'Mary', 
  salary:1000, 
  job_type:'QA', 
  calc: qaSalary 
}; 
 
console.log('Salary',bob.calc(bob.salary)); 
console.log('Salary',mary.calc(mary.salary)); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.