有没有更好的方法来编写此switch语句

时间:2019-02-12 21:59:37

标签: javascript switch-statement

考虑以下switch语句:

let doAttack = (firstAttacker, secondAttacker, statusOfBattle) => {
  statusOfBattle = createNonHitMessages(secondAttacker, firstAttacker, statusOfBattle);

  switch(statusOfBattle) {
    case statusOfBattle.enemyDodged && statusOfBattle.enemyBlocked:
      console.log('enemy Attack');
      break;
    case statusOfBattle.attackerDodged && statusOfBattle.attackerBlocked:
      console.log('attacker Attack');
      break;
    case statusOfBattle.enemyDodged:
      console.log('enemy Attack');
      break;
    case statusOfBattle.enemyBlocked:
      console.log('enemey Attack');
      break;
    case statusOfBattle.attackerBlocked:
      console.log('attacker attack');
      break;
    case statusOfBattle.attackerDodged:
      console.log('attacker attack');
      break;
    default:
      break;
  }

  return statusOfBattle
}

enemeyDodgedenemeyBlockedattackerBlockedattackerDodged都将返回truefalse

我真的不想写一个巨大的if语句,我对此没有什么反对,除了在我有这么多条件的情况下看起来不是很干净。

如果if语句是唯一的实现方法,但是我希望我可以在这样的switch语句中检查布尔值,以便保持其整洁和可读性。

我显然不了解switch语句的局限性。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

这不是switch的工作方式-在您的情况下,statusOfBattle会在括号之间对事物进行求值,并对与事物相等的值执行大小写。您的陈述将不匹配,因为statusOfBattle的属性将不等于statusOfBattle对象本身。

我不完全了解如何确定谁发动了攻击,但是无论您如何尝试使用带有一些逻辑运算符的简单if / else语句,

let doAttack = (firstAttacker, secondAttacker, statusOfBattle) => {
  statusOfBattle = createNonHitMessages(secondAttacker, firstAttacker, statusOfBattle);

  if (statusOfBattle.attackerDodged && !statusOfBattle.enemyBlocked) {
    return 'attacker attack';
  } else if (statusOfBattle.attackerBlocked) {
    return 'attacker attack';
  } else {
    return 'enemy attack';
  }
}

使您甚至可以使用?表达式来制作简短,美观的版本:

let doAttack = (firstAttacker, secondAttacker, statusOfBattle) => {
  statusOfBattle = createNonHitMessages(secondAttacker, firstAttacker, statusOfBattle);

  return statusOfBattle.attackerDodged ? 'attacker attack' : 'enemy attack';
}

答案 1 :(得分:0)

switch (a) {
    case x:
        // do something
        break;
    case y:
        // do something else
        break;
    case z:
        // do third thing
        break;
}

大致等同于:

if (a === x) {
    // do something
} else if (a === y) {
    // do something else
} else if (a === z) {
    // do third thing
}

因此您的代码将无法正常工作,因为它正在测试以下内容:

if (statusOfBattle === (statusOfBattle.enemyDodged && statusOfBattle.enemyBlocked))

由于statusOfBattle是对象,而statusOfBattle.enemyDodged && statusOfBattle.enemyBlockedtruefalse,因此它们将永远不相等。

我不是这种风格的忠实拥护者,但是您可以从以下内容开始做自己想做的事情:

switch (true) {
    ...
}