有没有更好(更干净)的方法来使用三元运算符(不重复代码)编写这个 JS 代码?
Posted
技术标签:
【中文标题】有没有更好(更干净)的方法来使用三元运算符(不重复代码)编写这个 JS 代码?【英文标题】:Is there a better(cleaner) way to write this JS code using ternary operators(without repeating code)? 【发布时间】: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 语句... 【参考方案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)
);
【讨论】:
以上是关于有没有更好(更干净)的方法来使用三元运算符(不重复代码)编写这个 JS 代码?的主要内容,如果未能解决你的问题,请参考以下文章
有没有一种干净的方法来使用 symfony 2.6 设置 websocket