使用 JavaScript 编写更好的条件语句

使用 JavaScript 编写更好的条件语句

在任何编程语言中,代码需要根据不同的条件在给定的输入中做不同的决定和执行相应的动作。例如,在一个游戏中,如果玩家生命点为0,游戏结束。在天气应用中,如果在早上被查看,显示一个日出图片,如果是晚上,则显示星星和月亮。在这篇文章中,我们将探索JavaScript中所谓的条件语句如何工作。如果你使用JavaScript工作,你将写很多包含条件调用的代码。条件调用可能初学很简单,但是还有比写一对对if/else更多的东西。这里有些编写更好更清晰的条件代码的有用提示。

  • 数组方法 Array.includes
  • 提前退出 / 提前返回
  • 用对象字面量或Map替代Switch语句
  • 默认参数和解构
  • 用 Array.every & Array.some 匹配全部/部分内容
  • 使用可选链和空值合并

数组方法 Array.includes

使用 Array.includes 进行多条件选择

例如:

function printAnimals(animal) {    if (animal === 'dog' || animal === 'cat') {        console.log(I have a ${animal});    }}console.log(printAnimals('dog')); // I have a dog

上面的代码看起来很好因为我们只检查了两个动物。然而,我们不确定用户输入。如果我们要检查任何其他动物呢?如果我们通过添加更多“或”语句来扩展,代码将变得难以维护和不清晰。

解决方案:

我们可以通过使用 Array.includes 来重写上面的条件

function printAnimals(animal) {
   const animals = ['dog', 'cat', 'hamster', 'turtle']; 
 
   if (animals.includes(animal)) {
     console.log(I have a ${animal});
   }
}
 
console.log(printAnimals('hamster')); // I have a hamster

这里,我们创建来一个动物数组,所以条件语句可以和代码的其余部分抽象分离出来。现在,如果我们想要检查任何其他动物,我们只需要添加一个新的数组项。我们也能在这个函数作用域外部使用这个动物数组变量来在代码中的其他任意地方重用它。这是一个编写更清晰、易理解和维护的代码的方法,不是吗?

提前退出 / 提前返回

这是一个精简你的代码的非常酷的技巧。我记得当我开始专业工作时,我在第一天学习使用提前退出来编写条件。

让我们在之前的例子上添加更多的条件。用包含确定属性的对象替代简单字符串的动物。

现在的需求是:

  • 如果没有动物,抛出一个异常
  • 打印动物类型
  • 打印动物名字
  • 打印动物性别
const printAnimalDetails = animal => {
  let result; // declare a variable to store the final value
 
  // condition 1: check if animal has a value
  if (animal) {
 
    // condition 2: check if animal has a type property
    if (animal.type) {
 
      // condition 3: check if animal has a name property
      if (animal.name) {
 
        // condition 4: check if animal has a gender property
        if (animal.gender) {
          result = ${animal.name} is a ${animal.gender} ${animal.type};;
        } else {
          result = "No animal gender";
        }
      } else {
        result = "No animal name";
      }
    } else {
      result = "No animal type";
    }
  } else {
    result = "No animal";
  }
 
  return result;
};
 
console.log(printAnimalDetails()); // 'No animal'
 
console.log(printAnimalDetails({ type: "dog", gender: "female" })); // 'No animal name'
 
console.log(printAnimalDetails({ type: "dog", name: "Lucy" })); // 'No animal gender'
 
console.log(
  printAnimalDetails({ type: "dog", name: "Lucy", gender: "female" })
); // 'Lucy is a female dog'

你觉得上面的代码怎么样?它工作得很好,但是代码很长并且维护困难。如果不使用lint工具,找出闭合花括号在哪都会浪费很多时间。? 想象如果代码有更复杂的逻辑会怎么样?大量的if..else语句。我们能用三元运算符、&&条件等语法重构上面的功能,但让我们用多个返回语句编写更清晰的代码。

const printAnimalDetails = ({type, name, gender } = {}) => {  if(!type) return 'No animal type';  if(!name) return 'No animal name';  if(!gender) return 'No animal gender';// Now in this line of code, we're sure that we have an animal with all //the three properties here.  return ${name} is a ${gender} ${type};}console.log(printAnimalDetails()); // 'No animal type'console.log(printAnimalDetails({ type: dog })); // 'No animal name'console.log(printAnimalDetails({ type: dog, gender: female })); // 'No animal name'console.log(printAnimalDetails({ type: dog, name: 'Lucy', gender: 'female' })); // 'Lucy is a female dog'

在这个重构过的版本中,也包含了解构和默认参数。默认参数确保如果我们传递undefined作为一个方法的参数,我们仍然有值可以解构,在这里它是一个空对象{}。通常,在专业领域,代码被写在这两种方法之间。另一个例子:

function printVegetablesWithQuantity(vegetable, quantity) {  const vegetables = ['potato', 'cabbage', 'cauliflower', 'asparagus'];  // condition 1: vegetable should be present   if (vegetable) {     // condition 2: must be one of the item from the list     if (vegetables.includes(vegetable)) {       console.log(I like ${vegetable});       // condition 3: must be large quantity       if (quantity >= 10) {         console.log('I have bought a large quantity');       }     }   } else {     throw new Error('No vegetable from the list!');   }}printVegetablesWithQuantity(null); //  No vegetable from the list!printVegetablesWithQuantity('cabbage'); // I like cabbageprintVegetablesWithQuantity('cabbage', 20); // 'I like cabbage// 'I have bought a large quantity'

现在,我们有:

  1. 1 if/else 语句过滤非法条件
  2. 3 级嵌套if语句 (条件 1, 2, & 3)

一个普遍遵循的规则是:在非法条件匹配时提前退出。

function printVegetablesWithQuantity(vegetable, quantity) {
 
  const vegetables = ['potato', 'cabbage', 'cauliflower', 'asparagus'];
 
   // condition 1: throw error early
   if (!vegetable) throw new Error('No vegetable from the list!');
 
   // condition 2: must be in the list
   if (vegetables.includes(vegetable)) {
      console.log(I like ${vegetable});
 
     // condition 3: must be a large quantity
      if (quantity >= 10) {
        console.log('I have bought a large quantity');
      }
   }
}

通过这么做,我们少了一个嵌套层级。当你有一个长的if语句时,这种代码风格特别好。我们能通过条件倒置和提前返回,进一步减少嵌套的if语句。查看下面的条件2,观察我们是怎么做的

function printVegetablesWithQuantity(vegetable, quantity) {  const vegetables = ['potato', 'cabbage', 'cauliflower', 'asparagus'];   if (!vegetable) throw new Error('No vegetable from the list!');    // condition 1: throw error early   if (!vegetables.includes(vegetable)) return;    // condition 2: return from the function is the vegetable is not in   //  the list   console.log(I like ${vegetable});  // condition 3: must be a large quantity  if (quantity >= 10) {      console.log('I have bought a large quantity');  }}

通过倒置条件2,代码没有嵌套语句了。这种技术在我们有很多条件并且当任何特定条件不匹配时,我们想停止进一步处理的时候特别有用。所以,总是关注更少的嵌套和提前返回,但也不要过度地使用。

温馨提示:本文最后更新于2022-08-11 21:31:35,某些文章具有时效性,若有错误或已失效,请在下方留言或联系木子李
© 版权声明
THE END
喜欢就支持一下吧
点赞5004赞赏 分享
评论 共3条
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片
    • Mzili的头像-木子李's Blog钻石会员MziliSVIP6作者广东省广州市 电信0
    • 热门评论
      Mzili的头像-木子李's Blog钻石会员MziliSVIP6作者广东省广州市 电信2