Better

Ethan的博客,欢迎访问交流

在JS中关于条件判断的5条建议

条件和循环是日常编程中最重要的方式,如何优雅的书写条件判断和循环呢,这里有五条建议,并不是什么高深的技能,而是应该在日常工作中加强这种书写意识

Array.includes

针对多重条件判断,可以使用Array.includes代替,不仅可以优雅代码,同时扩展性来的更强。比如如下代码

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

经过优化后,代码可以如下

function test(fruit) {
  // extract conditions to array
  const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

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

少嵌套,早返回

我们先看如下代码存在哪些问题

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

  // condition 1: fruit must has value
  if (fruit) {
    // condition 2: must be red
    if (redFruits.includes(fruit)) {
      console.log('red');

      // condition 3: must be big quantity
      if (quantity > 10) {
        console.log('big quantity');
      }
    }
  } else {
    throw('No fruit!');
  }
}

条件判断嵌套过多,试想,我想知道不满足条件逻辑,还需要判断代码的最后,这是很糟糕的阅读代码体验。优化技巧对于不满足条件,及早返回(inverting the conditions & return early)。我们在书写代码的时候,应该更多的思考如何减少if嵌套,代码看上去瞬间优雅很多,比如优化如下

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

  if (!fruit) throw('No fruit!'); // condition 1: throw error early
  if (!redFruits.includes(fruit)) return; // condition 2: stop when fruit is not red

  console.log('red');

  // condition 3: must be big quantity
  if (quantity > 10) {
    console.log('big quantity');
  }
}

缺省参数与解构

在JS书写代码中,我们经常需要检查null/undefined值,且赋予一个缺省值,比如如下代码

function test(fruit, quantity) {
  if (!fruit) return;
  const q = quantity || 1; // if quantity not provided, default to one

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

在ES6来临后,函数缺省参数和解构,我们就可以对这种代码说bye了,在形参的时候可以指定默认值

function test(fruit, quantity = 1) { // if quantity not provided, default to one
  if (!fruit) return;
  console.log(`We have ${quantity} ${fruit}!`);
}

上面只是演示了,原始类型的情况,如果参数是对象呢,你知道如果我们取空值的属性就会报错,如何避免这种情况,增强程序的健壮性呢,答案就是解构

// 优化前
function test(fruit) { 
  // printing fruit name if value provided
  if (fruit && fruit.name)  {
    console.log (fruit.name);
  } else {
    console.log('unknown');
  }
}

// 优化后
function test({name} = {}) {
  console.log (name || 'unknown');
}

Map/Object

我们可以通过Map数据类型或Object替换switch或if语句,这是一个很实用的技能,不仅可以减少判断或循环次数,而且更容易扩展,来个例子

function test(color) {
  // use switch case to find fruits in color
  switch (color) {
    case 'red':
      return ['apple', 'strawberry'];
    case 'yellow':
      return ['banana', 'pineapple'];
    case 'purple':
      return ['grape', 'plum'];
    default:
      return [];
  }
}

使用Object优化十分简单,我们这里看看使用Map如何做

function test(color) {
  // use Map to find fruits in color
  const fruitColor = new Map()
    .set('red', ['apple', 'strawberry'])
    .set('yellow', ['banana', 'pineapple'])
    .set('purple', ['grape', 'plum']);

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

使用Array.filter函数达到同样目的

function test(color) {
  // use Array filter to find fruits in color
  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' }   ];

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

Array迭代器函数

使用Array.every和Array.some减少循环,直接用代码演示下吧

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

  let isAllRed = true;

  // condition: all fruits must be red
  for (let f of fruits) {
    if (!isAllRed) break;
    isAllRed = (f.color == 'red');
  }

  console.log(isAllRed); // false
}

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

  // condition: short way, all fruits must be red
  const isAllRed = fruits.every(f => f.color == 'red');

  console.log(isAllRed); // false
}

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

  // condition: if any fruit is red
  const isAnyRed = fruits.some(f => f.color == 'red');

  console.log(isAnyRed); // true
}

来源



留言