--- title: 何が間違っている? JavaScript のトラブルシューティング slug: Learn/JavaScript/First_steps/What_went_wrong tags: - Article - Beginner - CodingScripting - Debugging - Developer Tools - Error - JavaScript - Learn - Tutorial - console.log - l10n:priority translation_of: Learn/JavaScript/First_steps/What_went_wrong ---
前の記事の「数字当てゲーム」を作っていて、動かないことはありませんでしたか?恐れることはありません。この記事では、そんな心配をしなくて済むように、JavaScript のエラーを見つけて直す方法を伝授します。
前提条件: | 基本的なコンピューターリテラシー、HTML および CSS の基本的な理解、JavaScript についての理解。 |
---|---|
目的: | コード内のシンプルな問題を修正し始める能力と自信を得る。 |
コードに誤りがある場合、一般的に以下の 2 つのうち、どちらかの誤りであることがよくあります。
まあ、こんなに単純ではありません。もっと深く追及していくと違う種類のエラーも出てくることでしょう。しかし、見習いのうちは上の分類で十分です。上記の 2 つの種類のエラーについて見ていきましょう。
始めるにあたり、数字当て (今回は当たらない) ゲームに戻りましょう。わざとエラーになるバージョンを見ていきます。Github に行って number-game-errors.html をローカルにコピーしてください (ライブ実行はこちらを見てください)。
注: もしかしたら、あなたにも直したいと思っているバージョンがあるかもしれませんね。ですが、まずはこちらで用意したバージョンを直してみてください。そうすれば、ここで教えるテクニックが身につきます。それから、あなた自身のプログラムに戻って直してみてください。
それでは、開発者コンソールで構文エラーがあるか調べてみましょう。それからエラーを修正します。どうやって修正すればいいかは今から教えます。
以前に開発者ツールの JavaScript コンソールで、簡単なコマンドを入力してもらったことがあったと思います (思い出せなければ、リンクを見て開き方を調べてください)。コンソールの何が便利かといえば、ブラウザーの JavaScript エンジンに読み込ませようとしている JavaScript コードに構文エラーがあれば、すべて教えてくれるのです。さあ、バグを潰していきましょう。
number-game-errors.html
ファイルを開いているタブを選択して、JavaScript コンソールを開いてください。以下のメッセージが表示されていますね。guessSubmit.addeventListener('click', checkGuess);
addEventListener()
のリンクを張っておきます。addeventListener
を addEventListener
に修正してエラーを直しましょう。注: TypeError: "x" is not a function のリファレンスページで、このエラーに関する詳細な説明が見られます。
Null
は「何もない」ことや「値がない」ことを表す特別な値です。つまり lowOrHi
が宣言されて初期化されているけれど、意味のある値ではない — つまり型も値もないということです。checkGuess() { ... }
ブロックの中) で発生したため、ページを読み込んだだけでは出てきませんでした。後に続く関数の記事を読み進めていけば分かりますが、内側の関数のスコープは外側の関数のスコープとは異なります。今回のケースでは、 86 行目の checkGuess()
関数が実行されるまで実行されず、エラーも発生していませんでした。lowOrHi.textContent = '今の予想は大きすぎです!';
lowOrHi
定数の textContent
プロパティに文字列を設定しようとしていますが、lowOrHi
定数に適切な値が設定されていないため上手く動きません。lowOrHi
が使用されている箇所をコードのほかの部分から探してみましょう。最初に見つかるのは 48 行目でしょう。
const lowOrHi = document.querySelector('lowOrHi');
null
になっているか確認するため以下のコードを直後の 49 行目に追加します。
console.log(lowOrHi);
注: console.log()
は値をコンソールに出力する、デバッグするときにとても便利な関数です。これで 48行目で lowOrHi
にセットしたはずの値がコンソールに出力されるでしょう。
console.log()
の結果をコンソールで見てみましょう。 lowOrHi
の値は null
でした。これで問題が 48 行目にあることがわかりました。document.querySelector()
メソッドが使用されています。ファイルの少し上のほうにある、問題となる{{htmlelement("p")}} 要素を見てみましょう。
<p class="lowOrHi"></p>
.
) で始まりますが、 48 行目で querySelector()
メソッドに渡された文字列にはドットがありません。これが問題でしょう! 48 行目の lowOrHi
を .lowOrHi
に変更してみてください。console.log()
の文は求めていた <p>
要素を表示しています。何とか次のエラーを潰すことができました!console.log()
の行は削除してもいいですし、後で使うために残しておいても大丈夫です。注: TypeError: "x" is (not) "y" のリファレンスページで、このエラーに関する詳細な説明が見られます。
addeventListener
を .addEventListener
に直してください。今回はゲームは上手く動いているようです。しかし、何度か動かしていると、予想すべき「ランダムな」数字が常に 1 であることに気づくでしょう。これはあまりやりたくないゲームですね!
これはゲームのロジックに間違いなく問題があります。ゲームはエラーとはなっていませんが、正しく動いてはいません。
randomNumber
変数にランダムな数値が最初にセットされる場所を検索してみましょう。ゲームの開始で推測するランダムな数字を保存しようとしているのは 44行目のあたりです。
let randomNumber = Math.floor(Math.random()) + 1;
randomNumber = Math.floor(Math.random()) + 1;
console.log()
にもう一度登場してもらいましょう。先ほどのそれぞれの行の直下に以下のコードを追加します。
console.log(randomNumber);
randomNumber
の値が常に 1 であることに気づきます。これを直すには、この行が何をしているのか考えなければなりません。まず Math.random()
を呼んでいます。これは 0 から 1 までのランダムな実数値を生成します。例えば 0.5675493843 などです。
Math.random()
次に Math.random()
の実行結果を Math.floor()
に渡して、一番近い整数に切り捨てています。そしてその結果に 1 を加えます。
Math.floor(Math.random()) + 1
0 から 1 のランダムな実数を切り捨てると、結果は常に 0 となり、それに 1 を加えることで常に 1 となります。ランダムな数を切り捨てる前に 100 を乗算しなければなりません。次のコードは 0 から 99 を返すでしょう。
Math.floor(Math.random()*100);
さらに 1 を加えることで、1 から 100 のランダムな数字を返してくれるようになります。
Math.floor(Math.random()*100) + 1;
先ほどの 2 行をそれぞれ修正してください。保存して再度読み込むと、思い通りに動くようになっているでしょう!
コードを書いていると、よくあるエラーは他にもあります。このセクションではそれらを紹介してみましょう。
たいてい、このエラーはコード行のどこかの末尾にセミコロン (;) がないことを意味しています。しかし、時にはもっと難解なこともあります。例えば checkGuess()
関数内のこの行を、
let userGuess = Number(guessField.value);
以下のように変更してみます。
let userGuess === Number(guessField.value);
そうすると、このエラーが吐かれます。違うことをやろうとしているように見えるのでしょう。値を変数に設定する代入演算子 (=
) と、等値演算子 (===
) を、これはある値が別の値と同じかどうかを判定して true
または false
を返しますが、間違わないようにしてください。
注: SyntaxError: missing ; before statement のリファレンスページで、このエラーに関する詳細な説明が見られます。
これは代入と比較を混同している別の症状でしょう。たとえば、checkGuess()
関数内の、この行を
if (userGuess === randomNumber) {
以下のように変更してみます。
if (userGuess = randomNumber) {
判定で常に true
が返るようになり、常にプレイヤーが勝ったことになってしまいます。気を付けましょう!
これは単純です。大体は関数やメソッドの呼び出しで閉じ括弧を忘れたことを表しています。
注: SyntaxError: missing ) after argument list のリファレンスページで、このエラーに関する詳細な説明が見られます。
たいてい、このエラーは JavaScript のオブジェクトの書き方が正しくないことに関連しているのですが、
function checkGuess() {
上記のコードを以下のように変えても起きるでしょう。
function checkGuess( {
この変更でブラウザーは関数の内容を関数の引数として渡しているように勘違いしてしまいます。括弧には気を付けましょう!
これは簡単ですね。たいていの場合、関数や条件ブロックの終わりの閉じ波括弧が抜けていることを表します。checkGuess()
関数の最後の閉じ波括弧を消すと発生します。
これらのエラーは文字列の始まりもしくは終わりの引用符が抜けていることを表します。最初のエラーは、文字列の始めの引用符の代わりに、ブラウザーが予期しない文字列を見つけた (string には実際に見つけた文字列が入ります) ことを表し、2 つ目のエラーは文字列が引用符で終わっていないことを表します。
どのエラーにも言えることですが、上の例でも見たように、考えてください。エラーが起きた時に、エラーが起きた行の番号をみて、その行にエラーがあるか見てみます。エラーはその行に存在しないこともありますし、上述した理由以外で起きることもあるということを心に留めておいてください。
注: SyntaxError: Unexpected token と SyntaxError: unterminated string literal のリファレンスページで、これらエラーに関する詳細な説明が見られます。
やっとここまで来ましたね。簡単な JavaScript プログラムのエラーを見つけ出すための基本が理解できました。コードの間違いを解決するのがいつも簡単とは限りませんが、特に学習の最初の過程では、うまくいかない時にも寝る時間を数時間節約し、多少早く進捗をあげられるでしょう。
{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}