javascript - 我试图理解 Javascript 中的这段嵌套对象

标签 javascript arrays function object

我正在关注 YouTube 上有关使用 Javascript 构建项目的教程。这段代码应该创建一个石头剪刀布游戏。我理解这段代码的大部分内容。但我的挑战是decideWinner 函数如何工作。变量 yourScore 如何将值传递到 rpsDatabase 中?以及如何调用这些函数?

//Rock, Paper, Scissors

function rpsGame(yourChoice) {
    var humanChoice, botChoice, results, message;

    humanChoice = yourChoice.id;
    botChoice = numberToChoice(randToRpsInt());
    results = decideWinner(humanChoice, botChoice);
    console.log(botChoice);
}

function randToRpsInt () {
    return Math.floor(Math.random() * 3);
}

function numberToChoice (number) {
    return ['rock', 'paper', 'scissors'][number];
}

function decideWinner (yourChoice, computerChoice) {
    var rpsDatabase = {
        'rock': {'scissors': 1, 'rock': 0.5, 'paper': 0},
        'paper': {'rock': 1, 'paper': 0.5, 'scissors': 0},
        'scissors': {'paper': 1, 'scissors': 0.5, 'rock': 0},
    };

    var yourScore = rpsDatabase[yourChoice][computerChoice];
    var computerScore = rpsDatabase[computerChoice][yourChoice];

    return [yourScore, computerScore];
}

function finalMessage([yourScore, computerScore]) {
    if (yourScore === 0) {
        return {'message': 'You lost!', 'color': 'red'};
    } else if (yourScore === 0.5) {
        return {'message': 'You tied!', 'color': 'yellow'}; 
    } else {
        return {'message': 'You won!', 'color': 'green'};
    }
}
.container-game {
    border: 1px solid black;
    width: 75%;    
    margin: 0 auto;
    text-align: center;
}

.flex-box-weapons {
    display: flex;
    border: 1px solid black;
    padding: 10px;
    flex-wrap: wrap;
    justify-content: space-around;
}

.flex-box-weapons img:hover {
    box-shadow: 0px 10px 50px rgba(37, 50, 233, 1);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ff9d90908b8c8b8d9e8fbfcad1cfd1cd" rel="noreferrer noopener nofollow">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <link rel="stylesheet" href="content/css/style.css">    
    <title>RPS</title>
</head>
<body>
    <div class="container-game">
        <h2>Challenge 3: Rock, Paper, Scissors</h2>
        <div class="flex-box-weapons" id="flex-box-weapons-div">
            <img id="Rock" alt="Rock" src="http://images.clipartpanda.com/rock-clipart-clipart-harvestable-resources-rock.png" width="150" height="150" onclick="rpsGame(this)">
            <img id="Paper" alt="Paper" src="
http://images.clipartpanda.com/paper-clipart-nexxuz-Loose-Leaf-Paper.png" width="150" height="150" onclick="rpsGame(this)">
            <img id="Scissors" alt="Scissors" src="https://thumbs.dreamstime.com/b/female-hand-sign-victory-sign-peace-sing-scissors-vector-color-flat-illustration-isolated-white-background-web-83128345.jpg" width="150" height="150" onclick="rpsGame(this)">
        </div>
    </div>

    <script src="content/Js/script.js">

    </script>
</body>
</html>

最佳答案

“变量yourScore如何将值传递到rpsDatabase?”

没有yourScore是在数据库中查找嵌套值的结果

您可以使用变量来查找对象的属性 []符号-

const myObject = { hello: "world", foo: "bar" }
const key = "hello"
console.log(myObject[key])
// "world"

您可以对许多 [][]... 进行排序查找嵌套属性 -

const myObject = { hello: { world: "earth" }}
const key1 = "hello"
const key2 = "world"
console.log(myObject[key1][key2])
// "earth"

“函数是如何被调用的?”

rpsGame单击其中一张图像时调用该函数。发生这种情况是因为每个 imgonclick="rpsGame(this)"


改进

我想对代码进行一些质量改进。

1.rpsDatabase每次 decideWinner 都会被重新定义叫做。这是不必要的,因为 rpsDatabase 的值永远不要(不应该)改变 -

const rpsDatabase = {
  rock: {scissors: 1, rock: 0.5, paper: 0},
  paper: {rock: 1, paper: 0.5, scissors: 0},
  scissors: {paper: 1, scissors: 0.5, rock: 0},
}

function decideWinner (yourChoice, computerChoice) {
  var yourScore = rpsDatabase[yourChoice][computerChoice]
  var computerScore = rpsDatabase[computerChoice][yourChoice]
  return [yourScore, computerScore]
}

2. 通过分隔rpsDatabase ,我们可以用它来减少 randToRpsInt 中的代码重复和numberToChoice 。相反,我们最终得到一个简单的 randomChoice功能-

function randomChoice () {
  const rand = Math.floor(Math.random() * 3)
  // no need to redefine ["rock", "paper", "scissors"] on each call!
  return Object.keys(rpsDatabase)[rand]
}

3. 选择编码胜利、失败或平局的值是任意的: 1 , 0 ,或0.5 。考虑这个替代方案 -

<表类=“s-表”> <标题> 结果 编码 <正文> 获胜 1 损失 -1 领带 0

这个新的rpsDatabase会写成 -

const rpsDatabase = {
  rock: {scissors: 1, rock: 0, paper: -1},
  paper: {rock: 1, paper: 0, scissors: -1},
  scissors: {paper: 1, scissors: 0, rock: -1},
};

现在,您不必测试与任意数字的相等性,而是可以编写 finalMessage以更自然的方式使用比较 >< -

function finalMessage ([yourScore, computerScore]) {
  if (yourScore > computerScore)
    return {message: 'You won!', color: 'green'}
  else if (computerScore > yourScore)
    return {message: 'You lost!', color: 'red'}
  else 
    return {message: 'You tied!', color: 'yellow'}
}

或者使用 switch 进行等效操作。也许你更喜欢这种形式 -

function finalMessage ([yourScore, computerScore]) {
  switch (true) {
    case yourScore > computerScore:
      return {message: 'You won!', color: 'green'}
    case computerScore > yourScore:
      return {message: 'You lost!', color: 'red'}
    default:
      return {message: 'You tied!', color: 'yellow'}
  }
}

4.使用addEventListener而不是onclick属性。这使得 HTML 和 JavaScript 更清晰地分离,从而使两者具有更大的可移植性 -

<form id="game">
  <button type="button" value="rock">🪨</button>
  <button type="button" value="paper">📃</button>
  <button type="button" value="scissors">✂️</button>
  <br>
  <output name="result"></output>
</form>
const game = document.forms.game

// attach `rpsGame` to `click` event on each `button`
for (const button of game.querySelectorAll("button"))
  button.addEventListener("click", rpsGame)

演示

这是一个包含上述建议的功能演示 -

const game = document.forms.game

const rpsDatabase = {
  rock: {scissors: 1, rock: 0, paper: -1},
  paper: {rock: 1, paper: 0, scissors: -1},
  scissors: {paper: 1, scissors: 0, rock: -1},
}

function rpsGame (event) {
  const humanChoice = event.target.value
  const botChoice = randomChoice()
  const result = decideWinner(humanChoice, botChoice)
  game.result.value = JSON.stringify(finalMessage(result))
}

function randomChoice () {
  const rand = Math.floor(Math.random() * 3)
  return Object.keys(rpsDatabase)[rand]
}

function decideWinner (yourChoice, computerChoice) {
  const yourScore = rpsDatabase[yourChoice][computerChoice]
  const computerScore = rpsDatabase[computerChoice][yourChoice]
  return [yourScore, computerScore]
}

function finalMessage ([yourScore, computerScore]) {
  if (yourScore > computerScore)
    return {message: 'You won!', color: 'green'}
  else if (computerScore > yourScore)
    return {message: 'You lost!', color: 'red'}
  else 
    return {message: 'You tied!', color: 'yellow'}
}

for (const button of game.querySelectorAll("button"))
  button.addEventListener("click", rpsGame)
<form id="game">
  <button type="button" value="rock">🪨</button>
  <button type="button" value="paper">📃</button>
  <button type="button" value="scissors">✂️</button>
  <br>
  <output name="result"></output>
</form>

关于javascript - 我试图理解 Javascript 中的这段嵌套对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68329222/

相关文章:

javascript,带有if else的div按钮

javascript - 无法将焦点设置在 Primereact 中的 Dropdown 组件上

javascript - 使用 anchor .attr href 作为计数器中数组的起点

arrays - 函数参数中可以有 "If"语句吗?

c - PostgreSQL C函数,如何返回文本数组

r - 如何跨运行应用函数

c++ - 在 C++ 函数中返回两种不同类型的两个值

javascript - 如何关闭带有链接或按钮等的html页面?

javascript - 如何在jquery验证引擎中指定自定义无效条件?

javascript - 拦截 react native webview 的每一个请求