重构支持可读性的级联条件语句

JavaScript是一种极其灵活的编程语言,用于构建几乎所有你能想到的东西,从网站、网络应用、桌面应用,到智能设备的UI、服务器端应用等等。

JavaScript的灵活性使其拥有广泛的功能集–但是,正如我们所知,它也对一些奇怪的行为负责,这些行为点燃了开发者的想象力。我们写的一些代码是独特的,适合以聪明和优雅的方式解决这些奇怪的问题;有些则不是。

在这篇文章中,我们将重点分析开发人员取代字斟句酌、令人困惑的条件语句的不同方式–特别是层叠式if/else ifswitch 语句。为什么呢?因为在JS中,我们可以做得更好,而不仅仅是使用if

三元,&& ,和|| 操作符

让我们用if ,介绍一个带有条件语句的简单函数,让我们用三元运算符对其进行重构。

if (condition) {
   return functionTrue();
} else {
   return functionFalse();
}

复制代码

我们上面的例子没有什么问题,但我们确实不必要地占用了几行代码,重复了关键词return 。三元运算符可以进行简化。

return condition ? functionTrue() : functionFalse();

复制代码

这不是更简单了吗?但它是如何工作的呢?

三元运算符是唯一一个需要三个操作数的JavaScript运算符:一个条件,后面有一个问号(?),一个真性条件的表达式,后面有一个冒号(:),最后是一个假性条件的表达式。下面是它的样子。

condition ? expressionIfTrue : expressionIfFalse

复制代码

请注意,必须同时提供truefalse 表达式才能使三元运算符工作。但是如果我们只需要在条件是真实的时候做一些事情呢?

JavaScript提供了其他简化表达式的方法,即利用运算符&&||

让我们看一个不同的例子,我们只需要在条件得到满足时执行一个语句。

if (condition) {
   console.log("it's true!");
}

复制代码

我们可以通过使用&& ,把这个语句改写成一个单行代码,像这样。

condition && console.log("it's true!");

复制代码

这样做的关键原因是,JavaScript在条件语句中从左到右读取操作数,并在可以使参数无效的时候退出。因此,在&& 的情况下,如果第一个语句是错误的,那么评估下一个语句就没有意义了,因为整个表达式都是错误的。

同样地,|| 操作符将继续评估操作数,直到其中一个是true ,或者整个表达式评估为false 。请看下面的例子。

trueCondition || console.log("Hello world!"); // does not execute the console.log
falseCondition || console.log("Hello world!"); // executes the console.log

复制代码

评估一个表达式的多个结果

通常情况下,当我们阅读或编写代码时,我们会发现多个嵌套的if 条件–比如下面这个函数,它接收一个水果的名字并返回其颜色。

function getColor(fruit) {
   if (fruit.toLowerCase() === 'apple') {
       return 'red';
   } else if (fruit.toLowerCase() === 'banana') {
       return 'yellow';
   } if (fruit.toLowerCase() === 'orange') {
       return 'orange';
   } if (fruit.toLowerCase() === 'blueberry') {
       return 'blue';
   } if (fruit.toLowerCase() === 'lime') {
       return 'green';
   }

   return 'unknown';
}

复制代码

即使代码按照预期执行了功能,也有几件事我们可以做得更好。首先,toLowerCase 这个方法对每个水果都被多次调用,这不仅会影响性能,还会使整个函数的可读性降低。

下一个优化是避免重复条件,这可以减少我们可能引入错误的情况,例如忘记在我们的某一行中包含toLowerCase 方法。

我们可以通过在函数的开头只调用一次方法并评估每个结果来快速解决这个问题–但我们可以通过使用一个 [switch](https://www.w3schools.com/js/js_switch.asp)语句。

function getColor(fruit) {
   switch(fruit.toLowerCase()) {
       case 'apple':
           return 'red';
       case 'banana':
           return 'yellow';
       case 'orange':
           return 'orange';
       case 'blueberry':
           return 'blue';
       case 'lime':
           return 'green';
       default:
           return 'unknown';
   }
}

复制代码

这看起来好多了,但还是感觉不对。有很多重复的关键词,这使得阅读起来很混乱。

下面是一个不同的方法–一个更聪明、更优雅的方法,就像我们在本文开头讨论的那样。

function getColor(fruit) {
   const fruits = {
       'apple': 'red',
       'banana': 'yellow',
       'orange': 'orange',
       'blueberry': 'blue',
       'lime': 'green',
   };

   return fruits[fruit.toLowerCase()] || 'unknown';
}

复制代码

简单漂亮。很容易识别出每种颜色对应的水果,我们没有重复关键词,而且读起来很清楚,很容易理解。

这种解决层叠式if 语句的方法被称为跳跃表。它的作用远远超过简单的文本或常量;让我们看看一个更复杂的例子。

构建地图对象

跳跃表的方法对于简单的文本和常量是很好的,但是在更复杂的情况下,比如if 语句有多行代码,有函数调用时,它将如何工作呢?

现在我们已经了解了如何简化语句,对于这些更复杂的情况,方法很简单–这完全是关于我们如何构建我们的Map对象。

让我们用两个数字和一个操作作为参数建立一个calculate 函数,并在这两个数字上返回操作的结果。

function calculate(number1, number2, operation) {
   const operations = {
       '+': (a, b) => a + b,
       '-': (a, b) => a - b,
       '*': (a, b) => a * b,
       '/': (a, b) => a / b,
   }

   return operations[operation]?.(number1, number2) ?? 'invalid operation';
}

复制代码

正如预期的那样,这段代码看起来非常干净,一个函数被清楚地分配给每个操作,以进行必要的计算,得到我们想要的结果。

看起来有点不同,也许很奇怪的是return 语句;但它背后的想法很简单,所以让我们把它分解一下。

operations[operation]?.(number1, number2)

复制代码

表达式的第一部分将简单地从字典中返回给定的操作,如果键存在则执行函数。如果键不存在,它将返回undefined 。这最后一部分要归功于可选的链式运算符

第二部分使用了nullish凝聚操作符,当它的左侧操作符是nullundefined ,它就返回它的右侧操作符,否则就返回左侧操作符。

?? 'invalid operation';

复制代码

所以,在我们的例子中,当操作数在字典中存在时,它将返回操作数的结果,否则它将返回一个invalid operation

总结

JavaScript是一种灵活的语言,提供了多种解决问题的方法。在这篇文章中,我们学习了传统的if 语句的各种替代方法,可以帮助你写出更清晰、更好的代码。

在你的代码库中拥有多种选择是很重要的,因为没有一个单一的解决方案会适合所有的情况。此外,JavaScript在不断发展,随着新版本的推出,会有新的方法被引入或发现,所以保持联系并阅读最新的文章以保持更新是有帮助的。

谢谢你的阅读!

The postRefactoring cascading conditionals in favor of readabilityappeared first onLogRocket Blog.

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享