Есть ли лучший способ написать этот оператор переключателя JavaScript - PullRequest
0 голосов
/ 13 февраля 2019

Рассмотрим следующую инструкцию переключения:

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
}

enemeyDodged, enemeyBlocked, attackerBlocked и attackerDodged все вернут true или false.

Я действительно не хочу писать гигантское заявление if, я ничего не имею против этого, кроме того, оно не выглядит очень чистым, когда у меня так много условий.

, если оператор if является единственным способомчтобы все шло отлично, но я надеялся, что смогу проверить логические значения в выражении switch таким образом, чтобы сохранить его чистым и читаемым.

Я явно не понимаю ограничений операторов switch.

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019
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.enemyBlocked это либо true, либо false, они никогда не будут равны.

Я не большой поклонник этого стиля, но вы можете делать то, что хотите, начиная с:

switch (true) {
    ...
}
0 голосов
/ 13 февраля 2019

Это не так, как 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';
}
...