基礎から学ぶJavaScript入門 90日コース | 実践的なJavaScript - Day 77:デバッグ実践

JavaScript 90日で身につけるJavaScript
スポンサーリンク
スポンサーリンク

Day 77:デバッグ実践

Day 77では、ブラウザーの開発者ツールを使って、JavaScriptの処理を一時停止し、1行ずつ動きを確かめる方法を学びます。今回の学習内容は、ブレークポイント、ステップ実行、変数の確認です。

プログラムに不具合があるとき、コードを何度も書き換えるだけでは、原因が見つからず遠回りになることがあります。デバッグでは、実行を途中で止め、どの行を通ったか、変数に何が入っているかを確認します。つまり、予想だけで直すのではなく、実際のプログラムの状態を観察して原因を探します。

デバッグとは

デバッグとは、プログラムの不具合の原因を見つけて修正する作業です。エラーが画面に出る場合だけでなく、「エラーは出ないけれど結果が間違っている」場合もデバッグの対象です。

初心者の方は、次の流れを基本にすると進めやすいです。

  • どんな操作で問題が起きるか再現します。
  • 本来どうなるはずかを明確にします。
  • 処理がどこまで進むかを確認します。
  • 関係する変数や条件を調べます。
  • 原因を特定して、必要な部分だけを修正します。
  • 修正後に同じ操作を試し、問題が解消したか確認します。

ブレークポイントとは

ブレークポイントは、指定した行でプログラムを一時停止させる目印です。停止中は、その時点の変数の値を確認したり、次の行へ進めたりできます。

ブレークポイントを置いた行は、実行がそこへ到達したときに止まります。通常、その行の処理を実行する前に停止するため、行を進めると処理後の値がどう変わったかを確かめられます。

ステップ実行でできること

一時停止中に、処理を少しずつ進める操作をステップ実行といいます。開発者ツールでは、主に次の操作を使います。ボタン名やキーボード操作はブラウザーによって異なることがあるため、画面上の操作ボタンも確認してください。

  • 再開:次のブレークポイントまで、またはプログラムの終了まで実行します。
  • ステップオーバー:現在の行を実行し、次の行へ進みます。関数呼び出しがあっても、その関数の中には入りません。
  • ステップイン:現在の行に関数呼び出しがある場合、その関数の中へ入ります。
  • ステップアウト:現在の関数の残りを実行し、呼び出し元へ戻ります。

初心者の方は、最初は「一行ずつ進める」ステップオーバーを中心に使い、関数の中身まで調べたいときにステップインを使うと理解しやすいです。

例題:合計金額が間違うプログラム

次のコードは、商品の価格を合計する例です。意図的に間違いを入れています。価格が1,200円、800円、500円なら、正しい合計は2,500円です。

const prices = [1200, 800, 500];
let total = 0;

for (const price of prices) {
  // 本来は、これまでの合計に価格を加える必要がある
  total = price;
}

console.log(`合計: ${total}円`);
JavaScript

このコードはエラーにならず、最後の価格である500円を表示します。つまり、文法エラーではなく、計算のロジックに問題があります。

ステップ1:問題を再現する

まずコードを実行し、結果が「合計: 500円」になることを確認します。次に、本来の結果が2,500円であると整理します。

「値が違う」というだけでなく、期待する値と実際の値を比べることが大切です。これにより、どの処理を調べるべきか見当をつけやすくなります。

ステップ2:ブレークポイントを置く

ブラウザーでアプリを開き、開発者ツールのSources(またはDebugger)画面を開きます。JavaScriptファイルを選び、total = price;の行番号の横をクリックすると、ブレークポイントを設定できます。

ファイルを選ぶ場所や開発者ツールの表示名はブラウザーによって少し異なります。画面から見つけにくい場合は、開発者ツール内のファイル一覧や検索機能を使います。

ステップ3:処理を実行して停止させる

ページを再読み込みするか、その処理を実行する操作を行います。ブレークポイントの行に到達すると、実行が一時停止します。

停止したら、開発者ツールのScope(スコープ)欄などで、現在見えている変数の値を確認できます。最初のループでは、totalが0、priceが1200であることを確認できます。

ステップ4:一行ずつ進めて変数を確認する

ステップオーバーで次の行へ進み、変数の値を観察します。

  • 1回目:`total`は`1200`になります。
  • 2回目:`total`は`800`になります。
  • 3回目:`total`は`500`になります。

この変化から、合計を積み上げず、毎回現在の価格で上書きしていることがわかります。変数の値を一つずつ追うと、不具合の原因を具体的に説明できます。

ステップ5:原因を直して再確認する

合計を積み上げるには、代入ではなく加算代入を使います。

const prices = [1200, 800, 500];
let total = 0;

for (const price of prices) {
  // これまでの合計に、今回の価格を加える
  total += price;
}

console.log(`合計: ${total}円`);
JavaScript

修正後にもう一度実行し、2,500円と表示されることを確認します。デバッグは、コードを書き換えたところで終わりではありません。修正後の動作確認まで行うのが基本です。

変数を確認するときのポイント

変数を見るときは、値だけでなく「どのタイミングの値なのか」も意識します。ループの途中とループ終了後では、同じ変数でも値が異なります。また、関数の中では、その関数内の変数と外側の変数が別々のスコープにあります。

  • 変数名と値を確認します。
  • 処理を一行進めたときの変化を確認します。
  • ループでは、何回目の繰り返しかも意識します。
  • 関数の中に入った場合は、呼び出し元との値の受け渡しを確認します。

関数の中を調べる

ステップインを使うと、呼び出された関数の中へ進めます。たとえば、合計計算を関数に分けた場合、呼び出し元から関数へ入って、引数や関数内の変数を調べられます。

// 価格の配列を受け取り、合計を返す
function calculateTotal(prices) {
  let total = 0;

  for (const price of prices) {
    // ループごとの値をブレークポイントで確認できる
    total += price;
  }

  return total;
}

const prices = [1200, 800, 500];

// この呼び出しでステップインすると関数の中へ進める
const total = calculateTotal(prices);

console.log(`合計: ${total}円`);
JavaScript

関数の中に原因がありそうな場合はステップインを使い、関数が正しいとわかっている場合はステップオーバーで先へ進むと、調査が効率的です。

条件付きブレークポイント

ループが何百回も繰り返される場合、毎回停止すると確認に時間がかかります。その場合は、特定の条件を満たしたときだけ停止する条件付きブレークポイントが便利です。たとえば、特定の価格のときだけ停止する、といった使い方ができます。

条件付きブレークポイントの設定方法はブラウザーによって異なります。行番号を右クリックするなどして設定します。まずは通常のブレークポイントに慣れてから試すとよいでしょう。

debugger文も使える

ソースコードにdebugger;を書くと、開発者ツールを開いた状態でその行に到達したとき、実行を一時停止できます。

const prices = [1200, 800, 500];
let total = 0;

for (const price of prices) {
  // 開発者ツールを開いて実行すると、この位置で停止する
  debugger;

  total += price;
}

console.log(total);
JavaScript

調査が終わったら、debugger;は削除します。残っていても開発者ツールを開いていなければ停止しない場合がありますが、不要なデバッグコードを完成版に残さない習慣が大切です。

コンソール出力との使い分け

console.log()で変数を表示する方法も便利です。短い確認ならconsole.log()、処理の流れを途中で止めて複数の変数や呼び出し状況を調べたいときはブレークポイント、というように使い分けられます。

ただし、デバッグ用のログには、APIキー、パスワード、個人情報などを出さないでください。共有するスクリーンショットや画面録画にも、秘密情報が映らないよう注意します。調査が終わったログやdebugger;は、必要性を確認して削除しましょう。

よくあるつまずき

ブレークポイントを置いたのに停止しない場合は、次の点を確認します。

  • 表示しているファイルが、実際に実行されているファイルか確認します。
  • ブレークポイントの行が実行経路に含まれているか確認します。
  • ページを再読み込みするなど、処理をもう一度実行します。
  • コードを変更したあとに、古いファイルを見ていないか確認します。
  • 実行が一時停止中なのか、すでに終了しているのか確認します。

また、デバッグ中にコードを変更した場合は、ブレークポイントの位置がずれることがあります。表示されているコードと実行中のコードが一致しているか確認しましょう。

Day 77の練習課題

次のような小さな不具合を自分で作り、ブレークポイントで原因を探してみましょう。

  • 配列の合計を求める処理で、合計値を毎回上書きする不具合を作ります。
  • 条件分岐の条件を一部変更し、予想と違う分岐へ進む理由を調べます。
  • 関数に渡した引数と、関数内で受け取った値を確認します。
  • ループの途中で停止し、繰り返しごとの変数の変化を記録します。

学習のために作る不具合は、練習用のコードだけで試してください。元のプロジェクトの大切なファイルを変更する前には、Gitでコミットして復元できる状態にしておくと安心です。

Day 77のゴール

Day 77では、次のことができるようになっていれば十分です。

  • ブレークポイントを設定して実行を一時停止できます。
  • ステップ実行で処理の流れを追えます。
  • 停止中に変数や引数の値を確認できます。
  • 期待値と実際の値を比べて原因を探せます。
  • 修正後に同じ操作をして、問題が解決したか確認できます。

まとめ

Day 77では、ブレークポイントでプログラムを止め、ステップ実行で一行ずつ進めながら、変数の値や処理の流れを確認する方法を学びました。デバッグでは、問題を再現し、期待する結果と実際の結果を比べ、観察した事実をもとに原因を絞り込むことが大切です。

コードを感覚だけで書き換えるのではなく、変数がどのタイミングでどう変化するかを確認すれば、原因を説明しながら修正できるようになります。まずは今回の合計計算の例を開発者ツールで追い、1回のループごとに値がどう変わるかを確かめてみてください。

タイトルとURLをコピーしました