JS 条件语句的 几条守则

JavaScript 工作时,我们经常和条件语句打交道,这里有5条让你写出更好/干净的条件语句的建议。

 

1.多重判断时使用 Array.includes

2.更少的嵌套,尽早 return

3.使用默认参数和解构

4.倾向于遍历对象而不是 Switch 语句

5.对 所有/部分 判断使用 Array.every & Array.some

 

1.多重判断时使用 Array.includes

让我们看一下下面这个例子:

// condition
function test(fruit) {
  if (fruit == 'apple' || fruit == 'strawberry') {
    console.log('red');
  }
}

第一眼,上面这个例子看起来没问题。如果我们有更多名字叫 cherry 和 cranberries 的红色水果呢?我们准备用更多的 || 来拓展条件语句吗?

我们可以用 Array.includes (Array.includes)重写条件语句。

function test(fruit) {
  const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

  if (redFruits.includes(fruit)) {
    console.log('red');
  }
}

我们把红色的水果(red fruits)这一判断条件提取到一个数组。这样一来,代码看起来更整洁。

 

2.更少的嵌套,尽早 Return

让我们拓展上一个例子让它包含两个条件。

  • 如果没有传入参数 fruit,抛出错误

  • 接受 quantity 参数,并且在 quantity 大于 10 时打印出来

function test(fruit, quantity) {
  const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

  // 条件 1: fruit 必须有值
  if (fruit) {
    // 条件 2: 必须是red的
    if (redFruits.includes(fruit)) {
      console.log('red');

      // 条件 3: quantity大于10
      if (quantity > 10) {
        console.log('big quantity');
      }
    }
  } else {
    throw new Error('No fruit!');
  }
}

// 测试结果
test(null); // error: No fruits
test('apple'); // print: red
test('apple', 20); // print: red, big quantity

在上面的代码, 我们有:

  • 1个 if/else 语句筛选出无效的语句

  • 3层if嵌套语句 (条件 1, 2 & 3)

我个人遵循的规则一般是在发现无效条件时,尽早Return。

/_ 当发现无效语句时,尽早Return _/

function test(fruit, quantity) {
  const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

  // 条件 1: 尽早抛出错误
  if (!fruit) throw new Error('No fruit!');

  // 条件 2: 必须是红色的
  if (redFruits.includes(fruit)) {
    console.log('red');

    // 条件 3: 必须是大质量的
    if (quantity > 10) {
      console.log('big quantity');
    }
  }
}

这样一来,我们少了一层嵌套语句。这种编码风格非常好,尤其是当你有很长的if语句的时候(想象你需要滚动到最底层才知道还有else语句,这并不酷)

我们可以通过 倒置判断条件 & 尽早return 进一步减少if嵌套。看下面我们是怎么处理判断 条件2 的:

/_ 当发现无效语句时,尽早Return _/

function test(fruit, quantity) {
  const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

  // 条件 1: 尽早抛出错误
  if (!fruit) throw new Error('No fruit!');
  // 条件 2: 当水果不是红色时停止继续执行
  if (!redFruits.includes(fruit)) return; 

  console.log('red');

  // 条件 3: 必须是大质量的
  if (quantity > 10) {
    console.log('big quantity');
  }
}

通过倒置判断条件2,我们的代码避免了嵌套语句。这个技巧在我们需要进行很长的逻辑判断时是非常有用的,特别是我们希望能够在条件不满足时能够停止下来进行处理。

而且这么做并不困难。问问自己,这个版本(没有嵌套)是不是比之前的(两层条件嵌套)更好,可读性更高?

但对于我,我会保留先前的版本(包含两层嵌套)。这是因为:

  • 代码比较短且直接,包含if嵌套的更清晰

  • 倒置判断条件可能加重思考的负担(增加认知载荷)

因此,应当尽力减少嵌套和尽早return,但不要过度。如果你感兴趣的话,可以看一下关于这个话题的一篇文章和 StackOverflow 上的讨论。

  • Avoid Else, Return Early by Tim Oxley

  • StackOverflow discussion on if/else coding style

  •  

3.使用默认参数和解构

我猜下面的代码你可能会熟悉,在JavaScript中我们总是需要检查 null / undefined的值和指定默认值:

function test(fruit, quantity) {
  if (!fruit) return;
  // 如果 quantity 参数没有传入,设置默认值为 1
  const q = quantity || 1; 

  console.log(`We have ${q} ${fruit}!`);
}

//test results
test('banana'); // We have 1 banana!
test('apple', 2); // We have 2 apple!

实际上,我们可以通过声明 默认函数参数 来消除变量 q。

function test(fruit, quantity = 1) {
  // 如果 quantity 参数没有传入,设置默认值为 1
  if (!fruit) return;
  console.log(`We have ${quantity} ${fruit}!`);
}

//test results
test('banana'); // We have 1 banana!
test('apple', 2); // We have 2 apple!

这更加直观,不是吗?注意,每个声明都有自己的默认参数.

例如,我们也能给fruit分配默认值:function test(fruit = 'unknown', quantity = 1)。

如果fruit是一个object会怎么样?我们能分配一个默认参数吗?

function test(fruit) { 
  // 当值存在时打印 fruit 的值
  if (fruit && fruit.name)  {
    console.log (fruit.name);
  } else {
    console.log('unknown');
  }
}

//test results
test(undefined); // unknown
test({ }); // unknown
test({ name: 'apple', color: 'red' }); // apple

看上面这个例子,我们想打印 fruit 对象中可能存在的 name 属性。否则我们将打印unknown。我们可以通过默认参数以及解构从而避免判断条件 fruit && fruit.name

// 解构 - 仅仅获取 name 属性
// 为其赋默认值为空对象
function test({name} = {}) {
  console.log (name || 'unknown');
}

// test results
test(undefined); // unknown
test({ }); // unknown
test({ name: 'apple', color: 'red' }); // apple

由于我们只需要 name 属性,我们可以用 {name} 解构出参数,然后我们就能使用变量 name 代替 fruit.name。

我们也需要声明空对象 {} 作为默认值。如果我们不这么做,当执行 test(undefined) 时,你将得到一个无法对 undefined 或 null 解构的的错误。因为在 undefined 中没有 name 属性。

如果你不介意使用第三方库,这有一些方式减少null的检查:

  • 使用 Lodash get函数

  • 使用Facebook开源的idx库(with Babeljs)

这是一个使用Lodash的例子:

function test(fruit) {
  // 获取属性名,如果属性名不可用,赋默认值为 unknown
  console.log(__.get(fruit, 'name', 'unknown'); 
}

// test results
test(undefined); // unknown
test({ }); // unknown
test({ name: 'apple', color: 'red' }); // apple

你可以在jsbin运行demo代码。除此之外,如果你是函数式编程的粉丝,你可能选择使用 Lodash fp,Lodash的函数式版本(方法变更为get或者getOr)。

 

4.倾向于对象遍历而不是Switch语句

让我们看下面这个例子,我们想根据 color 打印出水果:

function test(color) {
  // 使用条件语句来寻找对应颜色的水果
  switch (color) {
    case 'red':
      return ['apple', 'strawberry'];
    case 'yellow':
      return ['banana', 'pineapple'];
    case 'purple':
      return ['grape', 'plum'];
    default:
      return [];
  }
}

// test results
test(null); // []
test('yellow'); // ['banana', 'pineapple']

上面的代码看起来没有错误,但是我找到了一些累赘。用对象遍历实现相同的结果,语法看起来更简洁:

const fruitColor = {
  red: ['apple', 'strawberry'],
  yellow: ['banana', 'pineapple'],
  purple: ['grape', 'plum']
};

function test(color) {
  return fruitColor[color] || [];
}

或者你也可以使用 Map实现相同的结果:

const fruitColor = new Map()
    .set('red', ['apple', 'strawberry'])
    .set('yellow', ['banana', 'pineapple'])
    .set('purple', ['grape', 'plum']);

function test(color) {
  return fruitColor.get(color) || [];
}

Map是一种在 ES2015 规范之后实现的对象类型,允许你存储 key 和 value 的值。

但我们是否应当禁止switch语句的使用呢?答案是不要限制你自己。从个人来说,我会尽可能的使用对象遍历,但我并不严格遵守它,而是使用对当前的场景更有意义的方式。

 

Todd Motto有一篇关于 switch 语句对比对象遍历的更深入的文章,你可以在这个地方阅读

TL;DR; 重构语法

在上面的例子,我们能够用Array.filter 重构我们的代码,实现相同的效果。

const fruits = [
    { name: 'apple', color: 'red' }, 
    { name: 'strawberry', color: 'red' }, 
    { name: 'banana', color: 'yellow' }, 
    { name: 'pineapple', color: 'yellow' }, 
    { name: 'grape', color: 'purple' }, 
    { name: 'plum', color: 'purple' }
];

function test(color) {
  return fruits.filter(f => f.color == color);
}

有着不止一种方法能够实现相同的结果,我们以上展示了 4 种。

5.对 所有/部分 判断使用Array.every & Array.some

这最后一个建议更多是关于利用 JavaScript Array 的内置方法来减少代码行数。看下面的代码,我们想要检查是否所有水果都是红色:

const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'banana', color: 'yellow' },
    { name: 'grape', color: 'purple' }
  ];

function test() {
  let isAllRed = true;

  // 条件:所有水果都是红色
  for (let f of fruits) {
    if (!isAllRed) break;
    isAllRed = (f.color == 'red');
  }

  console.log(isAllRed); // false
}

代码那么长!我们可以通过 Array.every减少代码行数:

const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'banana', color: 'yellow' },
    { name: 'grape', color: 'purple' }
  ];

function test() {
  const isAllRed = fruits.every(f => f.color == 'red');

  console.log(isAllRed); // false
}

现在更简洁了,不是吗?相同的方式,如果我们想测试是否存在红色的水果,我们可以使用 Array.some 一行代码实现。

const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'banana', color: 'yellow' },
    { name: 'grape', color: 'purple' }
];

function test() {
  // 条件:任何一个水果是红色
  const isAnyRed = fruits.some(f => f.color == 'red');

  console.log(isAnyRed); // true
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: JavaScript中的条件语句用于根据不同的条件执行不同的代码块。常见的条件语句包括if语句、switch语句和三元运算符。 if语句用于根据条件执行不同的代码块,语法如下: if (条件) { // 条件为真时执行的代码块 } else { // 条件为假时执行的代码块 } switch语句用于根据不同的值执行不同的代码块,语法如下: switch (值) { case 值1: // 值等于值1时执行的代码块 break; case 值2: // 值等于值2时执行的代码块 break; default: // 值不等于任何一个case时执行的代码块 } 三元运算符用于根据条件返回不同的值,语法如下: 条件 ? 值1 : 值2 如果条件为真,则返回值1,否则返回值2。 ### 回答2: JavaScript语言中条件语句是一种非常常见并重要的语句,它能够根据某些条件执行一组特定的指令或代码块。JavaScript语言中的条件语句有if语句、if...else语句、if...else if...else语句和switch语句。 if语句是最简单的条件语句,它根据指定的条件来确定是否执行代码块。if语句由关键字if和条件表达式组成,当条件表达式为true时,执行相应的代码块,否则跳过该语句。以下是if语句的基本格式: ``` if(条件表达式) { // 当条件表达式为true时,执行这里的代码 } ``` if...else语句除了包含if语句的执行部分外,还额外添加了执行else语句对应的代码块,当条件表达式为false 时,执行这里的代码。以下是if...else语句的基本格式: ``` if(条件表达式) { // 当条件表达式为true时,执行这里的代码 } else { // 当条件表达式为false时,执行这里的代码 } ``` if...else if...else语句用于多向分支判断,它由多条if语句和一个可选的else部分组成,else部分指定了这些if语句都不满足条件时所需要执行的代码块。以下是if...else if...else语句的基本格式: ``` if(条件表达式1) { // 当条件表达式1为true时,执行这里的代码 } else if(条件表达式2) { // 当条件表达式2为true时,执行这里的代码 } else { // 执行这里的代码 } ``` switch语句也是一种选择语句,它可以判断变量的值与哪个case匹配,然后执行该case对应的代码块。如果所有的case都不匹配,那么就会执行default代码块。以下是switch语句的基本格式: ``` switch(变量) { case 值1: // 当变量等于值1时,执行这里的代码 break; case 值2: // 当变量等于值2时,执行这里的代码 break; default: // 执行这里的代码 break; } ``` 以上是JavaScript语言中条件语句的基础,熟练掌握它们对于JavaScript编程非常重要,它们可以帮助开发者更加自如地进行程序控制。 ### 回答3: JavaScript 是一种广泛使用的编程语言,它有许多的条件语句可供使用。条件语句是一种编程语言中常用的表达式,用于控制程序的执行流程。在 JavaScript 中,常用的条件语句包括 if 语句、switch 语句、三元运算符等。 首先是 if 语句。if 语句在编写 JavaScript 程序时经常用到,用于检查某个条件是否为真,如果为真则执行某段代码。if 语句的基本语法如下: ``` if (条件) { // 如果条件为真,执行此处的代码 } ``` 其中,条件是要检查的条件,如果条件为真,则执行花括号中的代码块。如果需要在条件为假时执行一些其他的代码,可以使用 else 语句。它的语法如下: ``` if (条件) { // 如果条件为真,执行此处的代码 } else { // 如果条件为假,执行此处的代码 } ``` 此外,还可以使用 else if 语句来检查多个条件。它的语法如下: ``` if (条件1) { // 如果条件1为真,执行此处的代码 } else if (条件2) { // 如果条件2为真,执行此处的代码 } else { // 如果所有条件都不为真,执行此处的代码 } ``` 接着是 switch 语句。switch 语句用于根据不同的条件执行不同的代码块。它的语法如下: ``` switch (表达式) { case 条件1: // 如果表达式等于条件1,执行此处的代码 break; case 条件2: // 如果表达式等于条件2,执行此处的代码 break; default: // 如果表达式不等于任何条件,执行此处的代码 } ``` 在 switch 语句中,表达式是要进行比较的值。根据表达式的值不同,会依次进行比较,如果表达式等于某个条件,则执行该条件所对应的代码块。如果没有任何一个条件匹配,则执行 default 代码块。 最后是三元运算符。三元运算符是一种用于简化 if 语句的表达式。它的语法如下: ``` 条件 ? 如果条件为真,执行此处的代码 : 如果条件为假,执行此处的代码 ``` 三元运算符由三个部分组成,分别是条件、问号(?)和冒号(:)。如果条件为真,则执行问号后面的代码,如果条件为假,则执行冒号后面的代码。 总而言之,条件语句JavaScript 中起着非常重要的作用,可以控制程序的执行流程。if 语句、switch 语句和三元运算符是常用的条件语句,掌握它们对于编写高效的 JavaScript 程序非常重要。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值