JavaScript をデバッグする

Sofia Emelianova
Sofia Emelianova

このチュートリアルでは、DevTools で JavaScript の問題をデバッグするための基本的なワークフローについて説明します。このチュートリアルをお読みいただくか、このチュートリアルの動画バージョンをご覧ください。

バグを再現する

デバッグの最初のステップは、常にバグを一貫して再現する一連のアクションを見つけることです。

  1. 新しいタブでこのデモを開きます
  2. [Number 1] ボックスに「5」と入力します。
  3. [数値 2] ボックスに「1」と入力します。
  4. [Add Number 1 and Number 2] をクリックします。ボタンの下に「5 + 1 = 51」というラベルが表示されます。結果は 6 になります。このバグを修正します。

5 + 1 の結果は 51 です。6 になっているはずです。

この例では、5 + 1 の結果は 51 です。6 になっているはずです。

ソースパネルの UI についての理解を深める

DevTools には、CSS の変更、ページ読み込みパフォーマンスのプロファイリング、ネットワーク リクエストのモニタリングなど、さまざまなタスクに対応するさまざまなツールが用意されています。[Sources] パネルでは JavaScript をデバッグします。

  1. DevTools を開き、[ソース] パネルに移動します。

    [Sources] パネル。

[ソース] パネルには、次の 3 つのセクションがあります。

[Sources] パネルの 3 つのセクション。

  1. ファイルツリーが表示された [Page] タブ。このページがリクエストするすべてのファイルがここに表示されます。
  2. [コードエディタ] セクション[Page] タブでファイルを選択すると、そのファイルの内容がここに表示されます。
  3. [Debugger] セクション。ページの JavaScript を検査するためのさまざまなツール。

    DevTools ウィンドウの幅が広い場合、デフォルトでは [Debugger] が [Code Editor] の右側に表示されます。この場合、[Scope] タブと [Watch] タブは、[Breakpoints] や [Call stack] などを折りたたみ可能なセクションとして結合します。

ワイド ウィンドウの右側にあるデバッガ。

ブレークポイントでコードを一時停止する

このような問題をデバッグする一般的な方法は、大量の console.log() ステートメントをコードに挿入して、スクリプトの実行時に値を検査することです。次に例を示します。

function updateLabel() {
  var addend1 = getNumber1();
  console.log('addend1:', addend1);
  var addend2 = getNumber2();
  console.log('addend2:', addend2);
  var sum = addend1 + addend2;
  console.log('sum:', sum);
  label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
}

console.log() メソッドで処理を完了することもできますが、ブレークポイントを使用すると、より迅速に処理を完了できます。ブレークポイントを使用すると、コードの実行中にコードを一時停止し、その時点のすべての値を調べることができます。ブレークポイントには console.log() メソッドに比べて次のような利点があります。

  • console.log() を使用する場合、コンソールにメッセージを表示するには、ソースコードを手動で開き、関連するコードを見つけて、console.log() ステートメントを挿入し、ページを再読み込みする必要があります。ブレークポイントを使用すると、コードの構造を知らなくても、関連するコードで一時停止できます。
  • console.log() ステートメントでは、検査する各値を明示的に指定する必要があります。DevTools にブレークポイントを使用すると、その時点でのすべての変数の値が表示されます。気づかないうちに、コードに影響を与える変数がある場合があります。

つまり、ブレークポイントを使用すると、console.log() メソッドよりも迅速にバグを見つけて修正できます。

一歩引いてアプリの動作について考えると、[Add Number 1 and Number 2] ボタンに関連付けられた click イベント リスナーで、誤った合計(5 + 1 = 51)が計算されるという知識に基づいて推測できます。そのため、click リスナーが実行される直前にコードを一時停止することをおすすめします。イベント リスナー ブレークポイントを使用すると、まさにそれを実現できます。

  1. [Debugger] セクションで、[Event Listener Breakpoints] をクリックしてセクションを展開します。DevTools に、[Animation] や [Clipboard] などの展開可能なイベント カテゴリのリストが表示されます。
  2. [マウス] イベント カテゴリの横にある arrow_right [開く] をクリックします。 DevTools に、クリックマウスダウンなどのマウスイベントのリストが表示されます。各イベントの横にはチェックボックスがあります。
  3. [クリック] チェックボックスをオンにします。これで、DevTools は、いずれかの click イベント リスナーが実行されると自動的に一時停止するように設定されました。

    [クリック] チェックボックスが有効になっています。

  4. デモに戻り、もう一度 [Add Number 1 and Number 2] をクリックします。DevTools がデモを一時停止し、[ソース] パネルでコード行をハイライト表示します。次のコード行で DevTools を一時停止します。

    function onClick() {
    

    コードの別の行で一時停止している場合は、正しい行で一時停止するまで [Resume Script Execution] を押します。

イベント リスナー ブレークポイントは、DevTools で利用できる多くのタイプのブレークポイントのうちの 1 つです。各タイプは最終的に、さまざまなシナリオを可能な限り迅速にデバッグするため、さまざまなタイプをすべて試す価値があります。それぞれのタイプを使用するタイミングと方法については、ブレークポイントでコードを一時停止するをご覧ください。

コードのステップ実行

バグの一般的な原因の 1 つは、スクリプトが誤った順序で実行された場合です。コードをステップ実行することで、コードの実行を 1 行ずつ確認して、想定とは異なる順序で実行されている場所を正確に特定できます。今すぐ試す:

  1. DevTools の [Sources] パネルで、[step_into Step into next function call] をクリックして、onClick() 関数の実行を 1 行ずつステップ実行します。DevTools で、次のコード行がハイライト表示されます。

    if (inputsAreEmpty()) {
    
  2. step_over [Step over next function call] をクリックします。

    DevTools は、ステップを踏むことなく inputsAreEmpty() を実行します。DevTools が数行のコードをスキップすることに注意してください。これは、inputsAreEmpty() が false と評価され、if ステートメントのコードブロックが実行されなかったためです。

これが、コードをステップ実行するための基本的な考え方です。get-started.js のコードを見ると、バグが updateLabel() 関数のどこかにあることがわかります。コードの各行をステップ実行するのではなく、別のタイプのブレークポイントを使用すると、バグが存在すると思われる場所の近くでコードを一時停止できます。

コード行ブレークポイントを設定する

コード行ブレークポイントは最も一般的なタイプのブレークポイントです。特定のコード行を一時停止したい場合は、コード行ブレークポイントを使用します。

  1. updateLabel() の最後のコード行を見てみましょう。

    label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
    
  2. コードの左側には、そのコードの行番号(32)が表示されています。[32] をクリックします。DevTools により、32 の上に青いアイコンが表示されます。これは、この行にコード行ブレークポイントがあることを意味します。DevTools は、このコード行が実行される前に常に一時停止するようになりました。

  3. [Resume script execution] をクリックします。スクリプトは 32 行目まで実行されます。29、30、31 行目で、DevTools は宣言の横に addend1addend2sum値を表示します。

DevTools は 32 行目のコード行ブレークポイントで一時停止します。

この例では、DevTools は 32 行目のコード行ブレークポイントで一時停止します。

変数値を確認する

addend1addend2sum の値は不審な点です。これらは引用符で囲まれており 文字列であることを意味しますこれは、バグの原因を説明する適切な仮説です。次に、さらに情報を収集します。DevTools には、変数値を調べるためのツールが多数用意されています。

方法 1: スコープを検査する

コード行で一時停止すると、[スコープ] タブに、その時点で定義されているローカル変数とグローバル変数が、各変数の値とともに表示されます。該当する場合、クロージャ変数も表示されます。一時停止しているコード行がない場合、[スコープ] タブは空です。

変数値を編集するには、その値をダブルクリックします。

[スコープ] ペイン。

方法 2: watch 式

[Watch] タブでは、変数値の推移をモニタリングできます。Watch は変数に限定されません。有効な JavaScript 式は [Watch] タブに保存できます。

今すぐ試す:

  1. [みる] タブをクリックします。
  2. [add Add watch expression] をクリックします。
  3. タイプ typeof sum
  4. Enter キーを押します。DevTools に typeof sum: "string" が表示されている。コロンの右側にある値が式の結果です。

[Watch Expression] ペイン

次のスクリーンショットは、typeof sum ウォッチ式を作成した後の [Watch] タブ(右下)を示しています。

疑わしいため、sum は数値であるべきなのに文字列として評価されています。これで、これがバグの原因であることが確認できました。

方法 3: コンソール

console.log() メッセージを表示するだけでなく、コンソールを使用して任意の JavaScript ステートメントを評価することもできます。デバッグについては、コンソールを使用してバグの修正の可能性をテストできます。今すぐ試す:

  1. コンソール ドロワーを開いていない場合は、Esc キーを押して開きます。DevTools ウィンドウの下部に開きます。
  2. コンソールで「parseInt(addend1) + parseInt(addend2)」と入力します。このステートメントは、addend1addend2 がスコープ内にあるコード行で一時停止しているため、正常に機能します。
  3. Enter キーを押します。DevTools がステートメントを評価し、6 を出力します。これは、デモで生成されることが想定される結果です。

スコープ内の変数を評価した後の [Console] ドロワー。

次のスクリーンショットは、parseInt(addend1) + parseInt(addend2) を評価した後の [Console] ドロワーを示しています。

修正を適用する

バグの修正が見つかった。あとは、コードを編集してデモを再実行して、修正を試すだけです。修正を適用するために DevTools を終了する必要はありません。JavaScript コードは DevTools UI 内で直接編集できます。今すぐ試す:

  1. [Resume script execution] をクリックします。
  2. コードエディタで、31 行目の var sum = addend1 + addend2var sum = parseInt(addend1) + parseInt(addend2) に置き換えます。
  3. command+S キー(Mac)または Ctrl+S キー(Windows、Linux)を押して変更を保存します。
  4. [label_off ブレークポイントを無効化] をクリックします。 色が青色に変わり、アクティブであることを示します。設定されている場合、DevTools は設定されているブレークポイントを無視します。
  5. さまざまな値でデモを試します。デモが正しく計算されるようになりました。

次のステップ

このチュートリアルでは、ブレークポイントを設定する方法を 2 つだけ紹介しました。DevTools には、他にも次のような多くの方法が用意されています。

  • 指定した条件が満たされた場合にのみトリガーされる条件付きブレークポイント。
  • キャッチされた例外またはキャッチされなかった例外のブレークポイント。
  • リクエストした URL が指定した部分文字列に一致する場合にトリガーされる XHR ブレークポイント。

それぞれのタイプを使用するタイミングと方法については、ブレークポイントでコードを一時停止するをご覧ください。

このチュートリアルでは説明していませんが、コードをステップ実行するためのコントロールがいくつかあります。詳しくは、コード行をステップオーバーするをご覧ください。