JS - Rock-paper-scissors游戏(全球与本地范围)

时间:2014-08-27 04:40:28

标签: javascript

如果我将var计算机和var状态都设为全局范围,任何人都可以帮助解释为什么游戏不起作用,但它适用于var humanResult& computerResult?

var humanResult = 0;
var computerResult = 0;
var status = document.getElementById("status");
var computer = (Math.floor( Math.random() * 3 ) + 1);

//Click on Rock, Paper, Scissors

document.getElementById('rock').onclick = clickRock;
document.getElementById('paper').onclick = clickPaper;
document.getElementById('scissors').onclick = clickScissors;

function clickRock() {
    // var computer = (Math.floor( Math.random() * 3 ) + 1);
    // status = document.getElementById("status");
    console.log(computer);
    if (computer  == 1) {
    status.innerHTML = "You played rock. The bot played rock you tied. :|"
    };

    if (computer  == 2) {
        computerResult++;
        status.innerHTML = "You played rock. The bot played paper you lose. :(";
    };

    if (computer  == 3) {
        humanResult++;
        status.innerHTML = "You played rock. The bot played scissors you win. :)";
    }

    document.getElementById('humanScore').innerHTML = humanResult;
    document.getElementById('computerScore').innerHTML = computerResult;
}

*我在codepen上放置了一整套代码供您查看:

v1(完美的工作):http://codepen.io/lindadesu09/pen/AKHbl

v2(不起作用):http://codepen.io/lindadesu09/pen/Dumat

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:0)

status div声明为全局变量时未更新的原因是,在浏览器的情况下,全局对象window已经有window.status属性。

window.status很特别,它用于在浏览器底部的status bar中设置状态文本。大多数现代浏览器不再显示状态栏,但处理它的API仍然存在。

由于状态文本只能是一个字符串,因此当您在全局上下文中var status = document.getElementById("status");时,DOM节点在被设置为window.status之前被强制转换为字符串。所以后来window.status包含字符串"[object HTMLDivElement]",而不是DOM节点。

设置字符串的.innerHTML属性不起作用。要解决此问题,只需将全局status变量重命名为其他内容,例如gameStatus等。

另一种防止这种情况的方法是通过将所有代码包装在Immediately-Invoked Function Expression (IIFE)中来完全不使用任何全局变量:

(function () {
  var humanResult = 0;
  var computerResult = 0;
  var status = document.getElementById("status");

  //Click on Rock, Paper, Scissors

  document.getElementById('rock').onclick = clickRock;
  document.getElementById('paper').onclick = clickPaper;
  document.getElementById('scissors').onclick = clickScissors;

  function clickRock() {
    var computer = (Math.floor( Math.random() * 3 ) + 1);

    if (computer  == 1) {
      test.innerHTML = "You played rock. The bot played rock you tied. :|"
    };

    if (computer  == 2) {
      computerResult++;
      status.innerHTML = "You played rock. The bot played paper you lose. :(";
    };

    if (computer  == 3) {
      humanResult++;
      status.innerHTML = "You played rock. The bot played scissors you win. :)";
    }

    document.getElementById('humanScore').innerHTML = humanResult;
    document.getElementById('computerScore').innerHTML = computerResult;
  }

  function clickPaper() {
     var computer = (Math.floor( Math.random() * 3 ) + 1),

    if (computer  == 1) {
      status.innerHTML = "You played paper. The bot played paper you tied. :|"
    };

    if (computer  == 2) {
      computerResult++;
      status.innerHTML = "You played paper. The bot played scissors you lose. :(";
    };

    if (computer  == 3) {
      humanResult++;
      status.innerHTML = "You played paper. The bot played rock you win. :)";
    }

    document.getElementById('humanScore').innerHTML = humanResult;
    document.getElementById('computerScore').innerHTML = computerResult;
  }

  function clickScissors() {
    var computer = (Math.floor( Math.random() * 3 ) + 1),

    if (computer  == 1) {
      status.innerHTML = "You played scissors. The bot played scissors you tied. :|"
    };

    if (computer  == 2) {
      computerResult++;
      status.innerHTML = "You played scissors. The bot played rock you lose. :(";
    };

    if (computer  == 3) {
      humanResult++;
      status.innerHTML = "You played scissors. The bot played rock you win. :)";
    }
    document.getElementById('humanScore').innerHTML = humanResult;
    document.getElementById('computerScore').innerHTML = computerResult;
  }
}());

我还试图摆脱一些冗余代码,很多东西都可以抽象成可重用的函数。每当你发现自己复制并粘贴大块代码时,通常会想出如何将代码抽象到另一个函数中,这样可以节省大量的时间和精力进行维护并添加大致相同的新功能的事情。

我会将此代码重构为this (jsFiddle)

(function () {
  var humanResult = 0,
    computerResult = 0,
    choices = ['rock', 'paper', 'scissors'],
    status = document.getElementById("status"),
    humanScore = document.getElementById('humanScore'),
    computerScore = document.getElementById('computerScore'),
    updateScores = function () {
      humanScore.innerHTML = humanResult;
      computerScore.innerHTML = computerResult;
    },
    makeChoser = function (player) {
      return function () {
        var result,
          computer = Math.floor(Math.random() * 3 );

        if (computer === player) {
          result = 'tied :|';
        } else {
          if (computer < player && !(computer === 0 && player === 2)) {
            result =  'win :)';
            humanResult++;
          } else {
            result = 'lose :(';
            computerResult++;
          }
        }

        status.innerHTML = 'You played ' + choices[player] + '. The bot played ' + choices[computer] + ' you ' + result;

        updateScores();
      };
    };

  document.getElementById('rock').onclick = makeChoser(0);
  document.getElementById('paper').onclick = makeChoser(1);
  document.getElementById('scissors').onclick = makeChoser(2);
}());

这几乎是代码行数的一半,并将所有评分逻辑保存在一个地方,如果有错误,您只需排除故障并修复一个地方而不是三个。