JavaScript 複雜判斷的更優雅寫法

發表於2018-11-14

前提

我們編寫js程式碼時經常遇到複雜邏輯判斷的情況,通常大家可以用if/else或者switch來實現多個條件判斷,但這樣會有個問題,隨著邏輯複雜度的增加,程式碼中的if/else/switch會變得越來越臃腫,越來越看不懂,那麼如何更優雅的寫判斷邏輯,本文帶你試一下。

舉個例子

先看一段程式碼

通過程式碼可以看到這個按鈕的點選邏輯:根據不同活動狀態做兩件事情,傳送日誌埋點和跳轉到對應頁面,大家可以很輕易的提出這段程式碼的改寫方案,switch出場:

嗯,這樣看起來比if/else清晰多了,細心的同學也發現了小技巧,case 2和case 3邏輯一樣的時候,可以省去執行語句和break,則case 2的情況自動執行case 3的邏輯。

這時有同學會說,還有更簡單的寫法:

上面程式碼確實看起來更清爽了,這種方法的聰明之處在於:將判斷條件作為物件的屬性名,將處理邏輯作為物件的屬性值,在按鈕點選的時候,通過物件屬性查詢的方式來進行邏輯判斷,這種寫法特別適合一元條件判斷的情況。

是不是還有其他寫法呢?有的:

這樣寫用到了es6裡的Map物件,是不是更爽了?Map物件和Object物件有什麼區別呢?

  1. 一個物件通常都有自己的原型,所以一個物件總有一個”prototype”鍵。
  2. 一個物件的鍵只能是字串或者Symbols,但一個Map的鍵可以是任意值。
  3. 你可以通過size屬性很容易地得到一個Map的鍵值對個數,而物件的鍵值對個數只能手動確認。

我們需要把問題升級一下,以前按鈕點選時候只需要判斷status,現在還需要判斷使用者的身份:

原諒我不寫每個判斷裡的具體邏輯了,因為程式碼太冗長了。

原諒我又用了if/else,因為我看到很多人依然在用if/else寫這種大段的邏輯判斷。

從上面的例子我們可以看到,當你的邏輯升級為二元判斷時,你的判斷量會加倍,你的程式碼量也會加倍,這時怎麼寫更清爽呢?

上述程式碼核心邏輯是:把兩個條件拼接成字串,並通過以條件拼接字串作為鍵,以處理函式作為值的Map物件進行查詢並執行,這種寫法在多元條件判斷時候尤其好用。

當然上述程式碼如果用Object物件來實現也是類似的:

如果有些同學覺得把查詢條件拼成字串有點彆扭,那還有一種方案,就是用Map物件,以Object物件作為key:

是不是又高階了一點點?

這裡也看出來Map與Object的區別,Map可以用任何型別的資料作為key。

我們現在再將難度升級一點點,假如guest情況下,status1-4的處理邏輯都一樣怎麼辦,最差的情況是這樣:

好一點的寫法是將處理邏輯函式進行快取:

這樣寫已經能滿足日常需求了,但認真一點講,上面重寫了4次functionA還是有點不爽,假如判斷條件變得特別複雜,比如identity有3種狀態,status有10種狀態,那你需要定義30條處理邏輯,而往往這些邏輯裡面很多都是相同的,這似乎也是筆者不想接受的,那可以這樣實現:

這裡Map的優勢更加凸顯,可以用正則型別作為key了,這樣就有了無限可能,假如需求變成,凡是guest情況都要傳送一個日誌埋點,不同status情況也需要單獨的邏輯處理,那我們可以這樣寫:

也就是說利用陣列迴圈的特性,符合正則條件的邏輯都會被執行,那就可以同時執行公共邏輯和單獨邏輯,因為正則的存在,你可以開啟想象力解鎖更多的玩法,本文就不贅述了。

總結

本文已經教你了8種邏輯判斷寫法,包括:

  1. if/else
  2. switch
  3. 一元判斷時:存到Object裡
  4. 一元判斷時:存到Map裡
  5. 多元判斷時:將condition拼接成字串存到Object裡
  6. 多元判斷時:將condition拼接成字串存到Map裡
  7. 多元判斷時:將condition存為Object存到Map裡
  8. 多元判斷時:將condition寫作正則存到Map裡

至此,本文也將告一段落,願你未來的人生裡,不只是有if/else/switch。

如果你對本文感興趣,請關注作者微信公眾號:“大轉轉fe”

相關文章