在 JavaScript 中复杂的条件判断经常会导致代码变得混乱,一长串的 if/else 或者 switch 会使代码块变得臃肿。 例如,假设我们有个函数需要根据实际业务知识对一段短语进行语义转换,只用 if/else 语句的结构如下:

function getTranslation(str) {
  if (str.toLowerCase() === 'stock') {
    return 'fall in stock';
  } else if (str.toLowerCase() === 'fund') {
    return 'welfare fund';
  } else if (str.toLowerCase() === 'bond') {
    return 'short-term liabilities';
  } else if (str.toLowerCase() === 'deposit') {
    return 'fixed deposit';
  }
  return 'finance';
}

这段代码的可读性并不高,而且还有重复的 toLowerCase() 语句。如果使用 switch 语句:

function getTranslation(str) {
  switch (str.toLowerCase()) {
    case 'stock':
      return 'fall in stock';
    case 'fund':
      return 'welfare fund';
    case 'bond':
      return 'short-term liabilities';
    case 'deposit':
      return 'fixed deposit';
    default:
      return 'finance';
  }
}

虽然只调用了一次 toLowerCase(),但是仍然觉得不那么可读,swtich 语句遇到更复杂的逻辑容易容易遗漏 break 导致错误。 可以使用对象以更简洁的方式实现上述功能:

function getTranslation(str) {
  const obj = {
    stock: 'fall in stock',
    fund: 'welfare fund',
    bond: 'short-term liabilities',
    deposit: 'fixed deposit',
  };
  return obj[str.toLowerCase()] ?? 'finance';
}

第九行最后一部分使用空合并运算符(??)来设置默认值。也就是只有 obj[str.toLowerCase()]为 null 或者 undefined(但不是 0 或者 false)时返回’finance’。这点很关键,因为我们可能会想合法的返回 0 或者 false,例如:

function getTranslation(str) {
  const obj = {
    true: true,
    false: false,
  };
  return obj[str.toLowerCase()] ?? 'not boolean';
}

当有更复杂的逻辑可以将函数作为值传递给对象的键并执行响应:

function calculate(num1, num2, action) {
  const actions = {
    add: (a, b) => a + b,
    subtract: (a, b) => a - b,
    multiply: (a, b) => a * b,
    divide: (a, b) => a / b,
  };
  return actions[action]?.(num1, num2) ?? 'Calculation is not recognised';
}

这里第 9 行使用了可选链操作符(?.)来执行已定义的响应,否则则返回默认字符串。

if-else 和 switch 的替代方法 (opens new window)