5種在JavaScript函數(shù)中重構(gòu)If / Else語句的方法

1、默認(rèn)參數(shù)
let sumFunctionThatMayBreak = (a, b, inconsistentParameter) => a+b+inconsistentParametersumFunctionThatMayBreak(1,39,2) // => 42sumFunctionThatMayBreak(2,40, undefined) // => NaN
對于許多人來說,解決該問題的本能方法是添加一條if/else語句:
let sumFunctionWithIf = (a, b, inconsistentParameter) => {if (inconsistentParameter === undefined){return a+b} else {return a+b+inconsistentParameter}}sumFunctionWithIf(1,39,2) // => 42sumFunctionWithIf(2,40, undefined) // => 42
但是,您可以簡化上述功能,并if/else通過實現(xiàn)默認(rèn)參數(shù)來消除邏輯:
let simplifiedSumFunction = (a, b, inconsistentParameter = 0) => a+b+inconsistentParametersimplifiedSumFunction(1, 39, 2) // => 42simplifiedSumFunction(2, 40, undefined) // => 42
2、或運(yùn)算符
上面的問題不能總是使用默認(rèn)參數(shù)來解決。有時,你可能處在需要使用if-else邏輯的情況下,尤其是在嘗試構(gòu)建條件渲染功能時。在這種情況下,通常可以通過以下方式解決問題:
let sumFunctionWithIf = (a, b, inconsistentParameter) => {if (inconsistentParameter === undefined || inconsistentParameter === null || inconsistentParameter === false){return a+b} else {return a+b+inconsistentParameter}}sumFunctionWithIf(1, 39, 2) // => 42sumFunctionWithIf(2, 40, undefined) // => 42sumFunctionWithIf(2, 40, null) // => 42sumFunctionWithIf(2, 40, false) // => 42sumFunctionWithIf(2, 40, 0) // => 42/// ?????? but:sumFunctionWithIf(1, 39, '') // => "40"
或這樣:
let sumFunctionWithTernary = (a, b, inconsistentParameter) => {inconsistentParameter = !!inconsistentParameter ? inconsistentParameter : 0return a+b+inconsistentParameter}sumFunctionWithTernary(1,39,2) // => 42sumFunctionWithTernary(2, 40, undefined) // => 42sumFunctionWithTernary(2, 40, null) // => 42sumFunctionWithTernary(2, 40, false) // => 42sumFunctionWithTernary(1, 39, '') // => 42sumFunctionWithTernary(2, 40, 0) // => 42
但是,你可以使用或(||)運(yùn)算符進(jìn)一步簡化它。|| 運(yùn)算符的工作方式如下:
當(dāng)左側(cè)為假值時,它將返回右側(cè)。
如果為真值,它將返回左側(cè)。
然后,解決方案可能如下所示:
let sumFunctionWithOr = (a, b, inconsistentParameter) => {inconsistentParameter = inconsistentParameter || 0return a+b+inconsistentParameter}sumFunctionWithOr(1,39,2) // => 42sumFunctionWithOr(2,40, undefined) // => 42sumFunctionWithOr(2,40, null) // => 42sumFunctionWithOr(2,40, false) // => 42sumFunctionWithOr(2,40, '') // => 42sumFunctionWithOr(2, 40, 0) // => 42
3、空位合并
但是,有時候,你確實想保留0或''作為有效參數(shù),而不能使用||來做到這一點(diǎn)。運(yùn)算符(如上例所示)。幸運(yùn)的是,從今年開始,JavaScript使我們可以訪問??。(空位合并)運(yùn)算符,僅當(dāng)左側(cè)為null或未定義時才返回右側(cè)。這意味著,如果你的參數(shù)為0或'',它將被視為此類。讓我們看一下實際情況:
let sumFunctionWithNullish = (a, b, inconsistentParameter) => {inconsistentParameter = inconsistentParameter ?? 0.424242return a+b+inconsistentParameter}sumFunctionWithNullish(2, 40, undefined) // => 42.424242sumFunctionWithNullish(2, 40, null) // => 42.424242/// ?????? but:sumFunctionWithNullish(1, 39, 2) // => 42sumFunctionWithNullish(2, 40, false) // => 42sumFunctionWithNullish(2, 40, '') // => "42"sumFunctionWithNullish(2, 40, 0) // => 42
4、可選鏈接
最后,當(dāng)處理不一致的數(shù)據(jù)結(jié)構(gòu)時,很難相信每個對象將具有相同的密鑰。看這里:
let functionThatBreaks = (object) => {return object.name.firstName}functionThatBreaks({name: {firstName: "Sylwia", lasName: "Vargas"}, id:1}) // ? "Sylwia"functionThatBreaks({id:2}) // ?? Uncaught TypeError: Cannot read property 'firstName' of undefined ??
發(fā)生這種情況是因為object.name是undefined,因此我們無法對其進(jìn)行調(diào)用firstName。
許多人通過以下方式處理這種情況:
let functionWithIf = (object) => {if (object && object.name && object.name.firstName) {return object.name.firstName}}functionWithIf({name: {firstName: "Sylwia", lasName: "Vargas"}, id:1) // "Sylwia"functionWithIf({name: {lasName: "Vargas"}, id:2}) // undefinedfunctionWithIf({id:3}) // undefinedfunctionWithIf() // undefined
但是,您可以使用新的JS功能(可選鏈接)簡化上述操作。可選鏈在每一步都會檢查返回值是否為undefined,如果是,它將僅返回該值而不拋出錯誤:
let functionWithChaining = (object) => object?.name?.firstNamefunctionWithChaining({name: {firstName: "Sylwia", lasName: "Vargas"}, id:1}) // "Sylwia"functionWithChaining({name: {lasName: "Vargas"}, id:2}) // undefinedfunctionWithChaining({id:3}) // undefinedfunctionWithChaining() // undefined
5、no-else-return和警告條款
笨拙的if / else語句(尤其是那些嵌套語句)的最后解決方案是no-else-return語句和guard子句。 因此,假設(shè)我們具有以下功能:
let nestedIfElseHell = (str) => {if (typeof str == "string"){if (str.length > 1) {return str.slice(0,-1)} else {return null}} else {return null}}nestedIfElseHell("") // => nullnestedIfElseHell("h") // => nullnestedIfElseHell("hello!") // => "hello"
no-else-return
現(xiàn)在,我們可以使用以下no-else-return語句簡化此函數(shù),因為無論如何我們返回的都是null:
let noElseReturns = (str) => {if (typeof str == "string"){if (str.length > 1) {return str.slice(0,-1)}}return null}noElseReturns("") // => nullnoElseReturns("h") // => nullnoElseReturns("hello!") // => "hello"
該no-else-return語句的好處是,如果不滿足條件,該函數(shù)將結(jié)束的執(zhí)行if-else并跳至下一行。你甚至可以不使用最后一行(return null),然后返回undefined。
注意:我實際上在前面的示例中使用了一個no-else-return函數(shù)。
警告條款
現(xiàn)在,我們可以更進(jìn)一步,并設(shè)置防護(hù)措施,甚至可以更早地結(jié)束代碼執(zhí)行:
let guardClauseFun = (str) => {// ? first guard: check the typeif (typeof str !== "string") return null// ? second guard: check for the lengthif (str.length <= 3) console.warn("your string should be at least 3 characters long and its length is", str.length)// otherwise:return str.slice(0,-1)}guardClauseFun(5) // => nullguardClauseFun("h") // => undefined with a warningguardClauseFun("hello!") // => "hello"
結(jié)論
你使用什么技巧來避免笨拙的if/else陳述?你可以在留言區(qū)給我們留言,讓我知道。
感謝你的閱讀。
學(xué)習(xí)更多技能
請點(diǎn)擊下方公眾號
![]()

