【问题标题】:Is there a better(cleaner) way to write this JS code using ternary operators(without repeating code)?有没有更好(更干净)的方法来使用三元运算符(不重复代码)编写这个 JS 代码?
【发布时间】:2019-08-17 11:36:34
【问题描述】:

所以我正在编写一个简单的 React.js 应用程序,只是有一个关于设置状态的问题,这可以做得更干净吗?

const enemy = this.state.enemy;
        if (this.state.isRock) {
            enemy === "rock"
                ? this.setState({ result: "Draw!" })
                : enemy === "paper"
                ? this.setState({ result: "You lose!" })
                : enemy === "scissors"
                ? this.setState({ result: "You win!" })
                : this.setState({ result: null });
        } else if (this.state.isPaper) {
            enemy === "rock"
                ? this.setState({ result: "You win!" })
                : enemy === "paper"
                ? this.setState({ result: "Draw!" })
                : enemy === "scissors"
                ? this.setState({ result: "You lose!" })
                : this.setState({ result: null });
        } else if (this.state.isScissors) {
            enemy === "rock"
                ? this.setState({ result: "You lose!" })
                : enemy === "paper"
                ? this.setState({ result: "You win!" })
                : enemy === "scissors"
                ? this.setState({ result: "Draw!" })
                : this.setState({ result: null });
        }

【问题讨论】:

  • 研究使用 switch 语句...

标签: javascript reactjs if-statement ecmascript-6 ternary-operator


【解决方案1】:

考虑到只有三种可能的状态(赢、输、平),我们只需要检查其中的两种。平局很容易检查,所以我们只需要输赢的状态。这是一个例子:

const enemy = this.state.enemy;
let wins = {
    "rock"     : "scissors",
    "paper"    : "rock" ,
    "scissors" : "paper",
}
let play = (this.state.isRock ? "rock" : (
  this.state.isPaper ? "paper" : (
    this.state.isScissors ? "scissors" : null
    )
  )
)

if (!wins[play]) {
    this.setState({ result: null })
} else if (enemy == play) {
    this.setState({ result: "Draw!" })
} else if (wins[play] == enemy) {
    this.setState({ result: "You win!" })
} else {
    this.setState({ result: "You lose!" })
}

【讨论】:

  • 是的,甚至可以通过将玩家的状态保存为字符串而不是这些 isXXX 布尔值来更简单:jsfiddle.net/5tfyqj6k
【解决方案2】:

您可以将条件作为地图的一部分,因为条件永远不会改变并设置状态。

const condition = {
  "rock": {
    "paper": "You lose!",
    "sccissors": "You win!",
    "rock": "Draw!"
  },
  "paper": {
    "rock": "You win!",
    "sccissors": "You lose!",
    "paper": "Draw!"
  },
  "sccissors": {
    "rock": "You lose!",
    "paper": "You win!",
    "sccissors": "Draw!"
  }
};

function getResult(enemy, isRock, isScissors, isPaper) {
  let result = null;
  
  if (isRock) {
    result = condition['rock'][enemy];
  } else if (isPaper) {
    result = condition['paper'][enemy];
  } else if (isScissors) {
    result = condition['scissors'][enemy];
  }
  
  return result;
}

const {
  isRock, 
  isScissors,
  isPaper,
  enemy
} = this.state;


this.setState({
  result: getResult(enemy, isRock, isScissors, isPaper)
})

【讨论】:

    【解决方案3】:

    我有一个有趣的方法,您可以尝试使用 for in 循环和一个 if 语句。

    您可以使用对象字面量来设置每个状态的值:

    const stateConditions = {
        "isRock": {
          "paper": "You lose!",
          "scissors": "You win!",
          "rock": "Draw!"
        },
        "isPaper": {
          "rock": "You win!",
          "scissors": "You lose!",
          "paper": "Draw!"
        },
        "isScissors": {
          "rock": "You lose!",
          "paper": "You win!",
          "scissors": "Draw!"
        }
      };
    

    在上面的对象中如果你做了 state = stateConditions['isRock'] 那么你会得到对应的 rock 条件

    使用 javascript this.state['isRock'] 与 this.state.isRock 相同。并且您可以使用属性来循环使用forin 的对象中的每个属性,因此您可以执行以下操作来查找当前状态。这样你就可以遍历所有可能的状态,看看 this.state['somestate'] 是否为真:

    for (let state in stateConditions) {
        if (this.state[state] === true) {
            // you found which state was true!
        }
    }
    

    最终代码:

    const conditions = {
        "isRock": {
          "paper": "You lose!",
          "scissors": "You win!",
          "rock": "Draw!"
        },
        "isPaper": {
          "rock": "You win!",
          "scissors": "You lose!",
          "paper": "Draw!"
        },
        "isScissors": {
          "rock": "You lose!",
          "paper": "You win!",
          "scissors": "Draw!"
        }
      };
    
      for (const state in conditions) {
          // check if this is the state
          if (this.state[state]) {
              this.setState({ result: condition[state][this.state.enemy] });
              break;
          }
      }
    

    这是replacing switch statements with object literals上的一篇有趣的文章

    【讨论】:

      【解决方案4】:

      对当前答案之一进行不同的旋转,以减少重复:

      const condition = {
        rock: {
          paper: -1,
          scissors: 1,
          rock: 0
        },
        paper: {
          paper: 0,
          scissors: -1,
          rock: 1
        },
        scissors: {
          paper: 1,
          scissors: 0,
          rock: -1
        }
      };
      
      function getResult({enemy, isRock, isScissors, isPaper}) {
        let result = null;
      
        if (isRock) {
          result = condition.rock[enemy];
        } else if (isPaper) {
          result = condition.paper[enemy];
        } else if (isScissors) {
          result = condition.scissors[enemy];
        }
      
        return result === -1 ? "You loose!" : result === 1 ? "You win!" : result === 0 ? "Draw!" : null;
      }
      
      this.setState({
        result: getResult(this.state)
      });
      

      【讨论】:

        猜你喜欢
        • 2020-03-14
        • 1970-01-01
        • 2021-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-22
        • 2012-08-14
        • 1970-01-01
        相关资源
        最近更新 更多