詳解如何替換項目中的if-else和switch
正文
在項目中,往往會看到很多的if-else
或者switch
,項目會變得很臃腫,而且不易閱讀,那么今天我們就來講講優(yōu)化方案
例如,假設我們有一個函數,它接受一個數字參數并返回其實際含義。使用 if/else 語句,它看起來像這樣:
function getTranslation(type) { if (type === 4) { return "forbidden_area"; } else if (type === 6) { return "elevator_area"; } else if (type === 7) { return "dangerous_area"; } else if (type === 10) { return "restricted_area"; } return "other_area"; }
這不是很好。它可讀性差。
我們可以通過使用 switch 語句優(yōu)化,如下所示:
function getTranslation(type) { switch (type) { case 4: return "forbidden_area"; case 6: return "elevator_area"; case 7: return "dangerous_area"; case 10: return "restricted_area"; default: return "other_area"; } }
但這仍然沒有什么可讀性。switch 語句也容易出錯。
在這種情況下,我們只是返回一個值,但是當你具有更復雜的功能時,很容易錯過 break 語句并引入錯誤。
替代方案
你可以使用對象以更簡潔的方式實現與上述相同的功能。讓我們看一個例子:
function getTranslation(type) { const types = { 4: 'forbidden_area', 6: 'elevator_area', 7: 'dangerous_area', 10: 'restricted_area' } return types[type] ?? 'other_area' }
我們有一個對象,其中鍵是條件,值是響應。然后我們可以使用方括號符號從傳入的參數中選擇對象的正確值。
函數中return types[type] ?? 'other_area'
使用無效合并來分配默認響應。這意味著如果 types[type]
為 null 或undefined(但不是 false 或 0 ),則返回默認字符串“other_area”。
|| vs ??
||
和??
都是指定默認值
讀取對象屬性的時候,如果某個屬性的值是null
或undefined
,有時候需要為它們指定默認值。常見做法是通過||
運算符指定默認值
const headerText = response.settings.headerText || 'Hello, world!'; const animationDuration = response.settings.animationDuration || 300; const showSplashScreen = response.settings.showSplashScreen || true;
上面的三行代碼都通過||
運算符指定默認值,但是這樣寫是錯的。開發(fā)者的原意是,只要屬性的值為null
或undefined
,默認值就會生效,但是屬性的值如果為空字符串或false
或0
,默認值也會生效。
為了避免這種情況,ES2020 引入了一個新的 Null 判斷運算符??
。它的行為類似||
,但是只有運算符左側的值為null
或undefined
時,才會返回右側的值。而||
是運算符左側的值為null
、undefined
、0
、''
或NaN
時,都會返回右側的值!
更復雜的邏輯
有時你可能需要在你的條件中執(zhí)行一些更復雜的邏輯。為此,你可以將函數作為值傳遞給對象鍵并執(zhí)行響應:
function calculate(action, num1, num2) { const actions = { add: (a, b) => a + b, subtract: (a, b) => a - b, multiply: (a, b) => a * b, divide: (a, b) => a / b, }; return actions[action]?.(num1, num2) ?? "Calculation is not recognised"; }
?.
有不懂的話,可以先看下面,我們正在選擇我們想要做的計算并執(zhí)行響應,傳遞兩個數字。你可以使用可選鏈接(最后一行代碼中的 ?.)來僅執(zhí)行已定義的響應。否則,將使用默認的返回字符串。
如果函數里的邏輯足夠復雜也可以把函數提取出來
function add(num1, num2) { return num1 + num2 } function subtract(num1, num2) { return num1 - num2 } function multiply(num1, num2) { return num1 * num2 } function divide(num1, num2) { return num1 / num2 } function calculate(action, num1, num2) { const actions = { add, subtract, multiply, divide } return actions[action]?.(num1, num2) ?? 'Calculation is not recognised' }
?.的說明
編程實務中,如果讀取對象內部的某個屬性,往往需要判斷一下,屬性的上層對象是否存在。比如,讀取message.body.user.firstName
這個屬性,安全的寫法是寫成下面這樣。
// 錯誤的寫法 const firstName = message.body.user.firstName || 'default'; // 正確的寫法 const firstName = (message && message.body && message.body.user && message.body.user.firstName) || 'default';
上面例子中,firstName
屬性在對象的第四層,所以需要判斷四次,每一層是否有值。
這樣的層層判斷非常麻煩,因此 ES2020 引入了“鏈判斷運算符”(optional chaining operator)?.
,簡化上面的寫法。
const firstName = message?.body?.user?.firstName || 'default';
上面代碼使用了?.
運算符,直接在鏈式調用的時候判斷,左側的對象是否為null
或undefined
。如果是的,就不再往下運算,而是返回undefined
。
下面是判斷對象方法是否存在,如果存在就立即執(zhí)行的例子。
iterator.return?.()
上面代碼中,iterator.return
如果有定義,就會調用該方法,否則iterator.return
直接返回undefined
,不再執(zhí)行?.
后面的部分。
下面是?.
運算符常見形式,以及不使用該運算符時的等價形式。
a?.b // 等同于 a == null ? undefined : a.b a?.[x] // 等同于 a == null ? undefined : a[x] a?.b() // 等同于 a == null ? undefined : a.b() a?.() // 等同于 a == null ? undefined : a()
上面代碼中,特別注意后兩種形式,如果a?.b()
和a?.()
。如果a?.b()
里面的a.b
有值,但不是函數,不可調用,那么a?.b()
是會報錯的。a?.()
也是如此,如果a
不是null
或undefined
,但也不是函數,那么a?.()
會報錯。
以上就是詳解如何替換項目中的if-else和switch的詳細內容,更多關于替換項目中if else switch的資料請關注腳本之家其它相關文章!
相關文章
Bootstrap樹形菜單插件TreeView.js使用方法詳解
這篇文章主要為大家詳細介紹了Bootstrap樹形菜單插件TreeView.js使用方法,一款非常酷的基于bootstrap的jQuery多級列表樹插件,具有一定的實用性,感興趣的小伙伴們可以參考一下2016-11-11