避免if語句的深層次嵌套


公司做了個搶紅包的限制,然后ajax請求的返回字段,要進行多層邏輯的判斷,想想是真惡心,雖然都是簡單邏輯,而且看別人以前寫的代碼,發現,哎,注釋能不能寫上吶,像我寫代碼都是細致到,哪怕初學者也能看懂這是要實現什么,還有盡量避免深層次的if嵌套,不然后面產品要加新需求,條件限制了,來個五六個if嵌套,,想想都蛋疼了,故而就查詢了一下如何優化,然后把之前的代碼給重新整理了下,哎,強迫症又犯了,明明不是自己挖的坑,還是想填了!


那么問題來了,在js開發中,如何減少if else語句的使用

代碼中嵌套的if/else結構往往導致代碼不美觀,也不易於理解。面向過程的開發中代碼有大量的IF ELSE,在java中可以用一些設計模式替換掉這些邏輯,那么在js中是否也有類似的方法用來盡可能減少代碼中的if/else嵌套呢?

有人認為:if else多就多唄,只要可讀性強,維護起來方便。jQuery.fn.init里就是一堆if else判斷,難道要質疑jQuery作者的水平了?並不是說if else多就不好,關鍵是看用的地方,jQuery.fn.init里除了if else判斷簡潔點,難道要改成switch?就算用工廠模式,還不是得做大量的if判斷。

代碼整潔強迫症患者必須要來個拋磚引玉:

1.


   
   
  
  
          
  1. if(a為真){
  2. a=a
  3. }else{
  4. a=b
  5. }

可寫成:a = a || b

2.


   
   
  
  
          
  1. if(a==b) {
  2. a=c
  3. } else {
  4. a=d
  5. }

可寫成:a = (a==b) ? c : d

3.

后台接口通常會返回這種數據:

fruit: 0 // 0=蘋果,1=梨子,2=桔子,3=檸檬,4=芒果...

這時寫if...else是最痛苦的。從沖哥那偷來個方法:


   
   
  
  
          
  1. var _f = [ '蘋果', '梨子', '桔子', '檸檬', '芒果'];
  2. shuiguo = _f[fruit];

建議:

第一步:優化if邏輯

人們考慮的東西到時候,都會把最可能發生的情況先做好准備。優化if邏輯的時候也可以這樣想:把最可能出現的條件放在前面,把最不可能出現的條件放在后面,這樣程序執行時總會按照帶啊名的先后順序逐一檢測所有的條件,知道發現匹配的條件才會停止繼續檢測。

if 的優化目標:最小化找到分支之前所判斷條件體的數量。if優化的方法:將最常見的條件放在首位。


   
   
  
  
          
  1. if (i < 5) {
  2. // 執行一些代碼
  3. } else if (i > 5 && i < 10) {
  4. // 執行一些代碼
  5. } else {
  6. // 執行一些代碼
  7. }

例如上面這個例子,只有在 i 值經常出現小於5的時候是最優化的。如果i值經常大於或者等於10的話,那么在進入正確的分支之前,就必須兩次運算條件體,導致表達式的平均運算時間增加。 if 中的條件體應該總是按照從最大概率到最小概率排列,以保證理論速度最快。

第二步:盡量少使用else

如果在函數中,可以使用 if + return ,先判斷錯誤條件,然后立馬結束函數,防止進入 else 分支。

舉個簡單的例子,后端返回數據,前端根據狀態進行不同操作


   
   
  
  
          
  1. $.ajax().done(function (res) {
  2. if (res.state === 'SUCCESS') {
  3. //TODO
  4. } else if (res.state === 'FAIL') {
  5. //TODO
  6. } else {
  7. //TODO
  8. }
  9. });

這里用if else不挺好的么,有啥問題么?不過我個人傾向於switch。

解決方法:

1. switch/case

switch和if else在性能上是沒有什么區別的,主要還是根據需求進行分析和選擇。

  • 如果條件較小的話選用if else比較合適。

  • 相反,條件數量較大的話,就建議選用switch。

一般來說,if else適用於兩個離散的值或者不同的值域。如果判斷多個離散值,使用switch更加合適。

在大多數的情況下switch比if else運行的更加快。

在大多數情況下,switch的性能不會比if else低。switch的確在實質上跟if else if 完全一樣的效果,不過在很多情況下,使用switch要比if else方便不少

比如經典的值等分支,匹配一些狀態常量的時候,比if else結構方便許多,不用反復寫xx == yy


   
   
  
  
          
  1. $.ajax().done(function (res) {
  2. switch (res.state) {
  3. case 'SUCCESS':
  4. //TODO
  5. break;
  6. case 'FAIL':
  7. //TODO
  8. break;
  9. default :
  10. //TODO
  11. }
  12. });

注意:千萬不要忘記在每一個case語句后面放一個break語句。也可以放一個return或者throw。case語句匹配expression是用===而不是==。

2.hash 表


   
   
  
  
          
  1. if (key == "Apple") {
  2. val = "Jobs";
  3. } else if (key == "microsoft"){
  4. val = "Gates";
  5. } else if (key == "Google"){
  6. val = "Larry";
  7. }

這個也可以用 switch case 解決,不過推薦的方法是 hash 表:


   
   
  
  
          
  1. var ceos = { "Apple": "Jobs", "microsoft": "Gates", "Google": "Larry"};
  2. val = ceos[key];

3.重構,用 OO 里面的繼承或者組合


   
   
  
  
          
  1. 1.如果是狗,則汪汪
  2. 2.如果是貓,則喵喵
  3. 3.如果是羊,則咩咩
  4. 4.如果是鴨,則嘎嘎

可以重構一下,改成 OO。


   
   
  
  
          
  1. *定義類: 動物(或者接口)
  2. *定義方法:叫
  3. *定義子類:狗、貓、羊、鴨
  4. *重寫方法 ---- 叫

也就是說將同的判斷按照功能,寫成函數,這樣也便於閱讀

比如我有一個方法根據類型獲取名稱,用if else會這樣


   
   
  
  
          
  1. function getName(type) {
  2. if ( type === 'monkey') {
  3. return 'monkey name';
  4. } else if ( type === 'cat') {
  5. return 'cat name';
  6. } else {
  7. return 'dog name';
  8. }
  9. }

如果寫成函數,改成下面的會更好


   
   
  
  
          
  1. function getName(type) {
  2. var data = {
  3. monkey: 'monkey name',
  4. cat: 'cat name',
  5. dog: 'dog name'
  6. }
  7. return data[type] ? data[type] : data[ 'dog'];
  8. }

硬要把設計模式添加到JS里不是不可以,但是要看情況。生搬硬套過來的東西然並卵啊。寫代碼記住三個字即可,短簡易。代碼短,讀起來簡單,維護容易,如果在性能和代碼長度上二選一,我肯定選代碼短,性能不行,加台服務器就是了。而冗長的代碼並不是加個程序員就能搞定的。

保持着這個心態寫代碼,寫出的東西離設計模式也不會差太多了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM