5种在JavaScript函数中重构If / Else语句的方法

1、默认参数
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通过实现默认参数来消除逻辑:
let simplifiedSumFunction = (a, b, inconsistentParameter = 0) => a+b+inconsistentParametersimplifiedSumFunction(1, 39, 2) // => 42simplifiedSumFunction(2, 40, undefined) // => 42
2、或运算符
上面的问题不能总是使用默认参数来解决。有时,你可能处在需要使用if-else逻辑的情况下,尤其是在尝试构建条件渲染功能时。在这种情况下,通常可以通过以下方式解决问题:
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
但是,你可以使用或(||)运算符进一步简化它。|| 运算符的工作方式如下:
当左侧为假值时,它将返回右侧。
如果为真值,它将返回左侧。
然后,解决方案可能如下所示:
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或''作为有效参数,而不能使用||来做到这一点。运算符(如上例所示)。幸运的是,从今年开始,JavaScript使我们可以访问??。(空位合并)运算符,仅当左侧为null或未定义时才返回右侧。这意味着,如果你的参数为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、可选链接
最后,当处理不一致的数据结构时,很难相信每个对象将具有相同的密钥。看这里:
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 🚨
发生这种情况是因为object.name是undefined,因此我们无法对其进行调用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子句。 因此,假设我们具有以下功能:
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
现在,我们可以使用以下no-else-return语句简化此函数,因为无论如何我们返回的都是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语句的好处是,如果不满足条件,该函数将结束的执行if-else并跳至下一行。你甚至可以不使用最后一行(return null),然后返回undefined。
注意:我实际上在前面的示例中使用了一个no-else-return函数。
警告条款
现在,我们可以更进一步,并设置防护措施,甚至可以更早地结束代码执行:
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"
结论
你使用什么技巧来避免笨拙的if/else陈述?你可以在留言区给我们留言,让我知道。
感谢你的阅读。
学习更多技能
请点击下方公众号
![]()

