JavaScriptのトラブルシューティング

エラーの種類

どの言語にもつきもののエラー2種類

数字当て(当たらない)ゲームのデバッグ

number-game-errors.html
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5.  
  6. <title>Number guessing game</title>
  7.  
  8. <style>
  9. html {
  10. font-family: sans-serif;
  11. }
  12. body {
  13. width: 50%;
  14. max-width: 800px;
  15. min-width: 480px;
  16. margin: 0 auto;
  17. }
  18. .lastResult {
  19. color: white;
  20. padding: 3px;
  21. }
  22. </style>
  23. </head>
  24.  
  25. <body>
  26. <h1>Number guessing game</h1>
  27.  
  28. <p>We have selected a random number between 1 and 100. See if you can guess it in 10 turns or less. We'll tell you if your guess was too high or too low.</p>
  29.  
  30. <div class="form">
  31. <label for="guessField">Enter a guess: </label><input type="text" id="guessField" class="guessField">
  32. <input type="submit" value="Submit guess" class="guessSubmit">
  33. </div>
  34.  
  35. <div class="resultParas">
  36. <p class="guesses"></p>
  37. <p class="lastResult"></p>
  38. <p class="lowOrHi"></p>
  39. </div>
  40.  
  41. </body>
  42.  
  43. <script>
  44. let randomNumber = Math.floor(Math.random()) + 1;
  45.  
  46. const guesses = document.querySelector('.guesses');
  47. const lastResult = document.querySelector('.lastResult');
  48. const lowOrHi = document.querySelector('lowOrHi');
  49. const guessSubmit = document.querySelector('.guessSubmit');
  50. const guessField = document.querySelector('.guessField');
  51.  
  52. let guessCount = 1;
  53. let resetButton;
  54.  
  55. function checkGuess() {
  56.  
  57. let userGuess = Number(guessField.value);
  58. if(guessCount === 1) {
  59. guesses.textContent = 'Previous guesses: ';
  60. }
  61. guesses.textContent += userGuess + ' ';
  62.  
  63. if(userGuess === randomNumber) {
  64. lastResult.textContent = 'Congratulations! You got it right!';
  65. lastResult.style.backgroundColor = 'green';
  66. lowOrHi.textContent = '';
  67. setGameOver();
  68. } else if(guessCount === 10) {
  69. lastResult.textContent = '!!!GAME OVER!!!';
  70. setGameOver();
  71. } else {
  72. lastResult.textContent = 'Wrong!';
  73. lastResult.style.backgroundColor = 'red';
  74. if(userGuess < randomNumber) {
  75. lowOrHi.textContent = 'Last guess was too low!';
  76. } else if(userGuess > randomNumber) {
  77. lowOrHi.textContent = 'Last guess was too high!';
  78. }
  79. }
  80.  
  81. guessCount++;
  82. guessField.value = '';
  83. guessField.focus();
  84. }
  85. guessSubmit.addeventListener('click', checkGuess);
  86.  
  87. function setGameOver() {
  88. guessField.disabled = true;
  89. guessSubmit.disabled = true;
  90. resetButton = document.createElement('button');
  91. resetButton.textContent = 'Start new game';
  92. document.body.appendChild(resetButton);
  93. resetButton.addeventListener('click', resetGame);
  94. }
  95.  
  96. function resetGame() {
  97. guessCount = 1;
  98.  
  99. const resetParas = document.querySelectorAll('.resultParas p');
  100. for(let i = 0; i < resetParas.length; i++) {
  101. resetParas[i].textContent = '';
  102. }
  103. resetButton.parentNode.removeChild(resetButton);
  104.  
  105. guessField.disabled = false;
  106. guessSubmit.disabled = false;
  107. guessField.value = '';
  108. guessField.focus();
  109.  
  110. lastResult.style.backgroundColor = 'white';
  111.  
  112. randomNumber = Math.floor(Math.random()) + 1;
  113. }
  114. </script>
  115. </html>

構文エラー

TypeError: guessSubmit.addeventListener is not a function  number-game-errors.html:85:15
number-game-errors.html の85行15文字目でエラーがあるよって言う見かたをする
これはaddEventListenerの打ち間違い(構文エラー)
JavaScriptは関数名の大文字小文字を区別するから注意

TypeError: lowOrHi is null  number-game-errors.html:77:7
77行目lowOrHiTextContentに値を設定しようとしてエラー

コードの最初から辿って最初にlowOrHiが出てくる宣言部

  1. const lowOrHi = document.querySelector('lowOrHi');

console.log()
括弧内に書いた変数の値をコンソールに出力する関数

これでlowOrHiを見るとNull
さっきの宣言部をよく見るとクラスを選択しているように見えてドット(.)が抜けているからできていない
ついでに93行目addEventListenerの打ち間違いも潰しておく

論理エラー

実はこのゲームは予想する値が常に1になっている欠陥品

  1. let randomNumber = Math.floor(Math.random()) + 1;

Math.random()Math.floor()関数の入れ子に1を足してそれをrandomNumberとしている
Math.random()は0以上1未満の乱数を返す関数 Math.floor()は括弧内の値の少数点以下を切り捨てる関数
つまり0以上1未満の乱数の少数点以下を切り捨ててそれに1を足したものを代入
これじゃあ常に1になる

Math.random()に100をかけて0以上100未満の乱数が出て来るようにする
その小数点以下を切り捨てそれに1を足すことで1以上101未満(100以下)の整数を取り出す

  1. let randomNumber = Math.floor(Math.random() * 100) + 1;

これでバグ取りはおしまい

その他のよくあるエラー

SyntaxError: missing ; before statement
末尾にセミコロン(;)がないよ

SyntaxError: missing ) after argument list
関数とかメソッドの閉じ括弧がないよ

SyntaxError: missing } after function body
関数の末尾の閉じ波括弧がないよ

SyntaxError: missing : after property id
オブジェクト初期化したいんだけどコロン(:)がないからプロパティのキーと値がどこにあるかわからないよ
(関数定義の時に閉じ括弧を忘れると出ることがある)

SyntaxError: expected expression, got '[文字列]'
SyntaxError: unterminated string literal
文字列がどこまでかわからないよ たぶん'[文字列]'になってないよ
(文字列の最後のクォーテーションの付け忘れ)

参考: https://developer.mozilla.org/ja/docs/Learn/JavaScript/First_steps/What_went_wrong

learnJS Home