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

共 5787字,需浏览 12分钟

 ·

2021-05-11 08:51

英文 | https://betterprogramming.pub/5-ways-to-refactor-if-else-statements-in-javascript-functions-2865a4bbfe29
翻译 | 小爱

在本文中,我将介绍5种通过不必要的if-else语句来整理代码的方法。我将讨论默认参数,或(||)运算符,空位合并,可选链no-else-returns,和保护子句。

1、默认参数

你知道在使用不一致的API时会感到这种感觉,并且代码中断是因为某些值是undefined?
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 : 0    return 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 || 0    return 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.424242    return 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}) // undefined  functionWithIf({id:3}) // undefined  functionWithIf() // undefined

但是,您可以使用新的JS功能(可选链接)简化上述操作。可选链在每一步都会检查返回值是否为undefined,如果是,它将仅返回该值而不抛出错误:

let functionWithChaining = (object) => object?.name?.firstName   functionWithChaining({name: {firstName: "Sylwia", lasName: "Vargas"}, id:1}) // "Sylwia"  functionWithChaining({name: {lasName: "Vargas"}, id:2}) // undefined  functionWithChaining({id:3}) // undefined  functionWithChaining() // 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("") // => null nestedIfElseHell("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("") // => null noElseReturns("h") // => nullnoElseReturns("hello!") // => "hello"

该no-else-return语句的好处是,如果不满足条件,该函数将结束的执行if-else并跳至下一行。你甚至可以不使用最后一行(return null),然后返回undefined。

注意:我实际上在前面的示例中使用了一个no-else-return函数。

警告条款

现在,我们可以更进一步,并设置防护措施,甚至可以更早地结束代码执行:

let guardClauseFun = (str) => {    // ✅ first guard: check the type    if (typeof str !== "string") return null    // ✅ second guard: check for the length    if (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) // => null guardClauseFun("h") // => undefined with a warningguardClauseFun("hello!") // => "hello"

结论

你使用什么技巧来避免笨拙的if/else陈述?你可以在留言区给我们留言,让我知道。

感谢你的阅读。

学习更多技能

请点击下方公众号

浏览 66
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报