「ブレークポイントを使用したデバッグ」 Chrome DevTools Tips集 #2

今回は、Sourcesタブの機能である、ブレークポイントの設定機能について、解説します。普段でバッグをするときは console.log() を使用していると思います。しかし、ブレークポイントを設定して、Sourceタブ内でデバッグをすることによって、より効率的にデバッグを行うことができます。

今回のブログはこんな方におすすめ!
  • Sourcesタブの使い方を知りたい方
  • 普段 console.log() を使用してデバッグをしていて、より効率的にデバッグをしたいと考えている方
  • コーディング力だけでなくデバッグ力も大切だと考えている方

ブレークポイントを使用したデバッグ方法

ブレークポイントとは、設定することで、プログラムの実行を任意の場所で一時停止し、停止した場所の変数の状態やコールスタック(関数の呼び出し経路)を確認できます。他にも、停止した場所からコードの実行を一つ一つ自分で進めることができます。

次のコードを例として、ブレークポイントとの使い方を解説していきます。

↑のコードの簡単な説明といたしましては、配列で渡した数値の合計を返すsum関数と、平均値を表す average 関数を定義しています。average 関数の内部では、sum 関数を使用しています。

average 関数を実行したときの動作をブレークポイントを使って追いかけます。

ブレークポイントの設定方法

ブレークポイントを設定するには、デベロッパーツールのSourcesパネルを使います。左のツリーからJSファイルを選択し、ファイルの行数部分をクリックすることでブレイクポイントを設定できます。例では、 average の最初の行(9行目)をクリックします。

ブレークポイントが設定できると↑画像のように、青い矢印のようなマークが付きます。この状態でリロードすると、ブレークポイントを設定した9行目で処理が止まります。

この状態では、JavaScriptが青い背景の行の前で完全にストップした状態です。注意していただいたいのが、青い背景の行ではなく、前だということです。つまり、青い背景の行は、まだ実行されていません。また、ブラウザのスクロールなども動きません。ページの読込中であれば、このスクリプト以降のHTMLのレンダリングも行われず、ブラウザのページのタブには、読込中の表示が出たままの状態です。

また、DevTools上から設定する方法の他に、コード上からブレークポイントを設定する方法もあります。↓のように debugger 文をブレークポイントを指定したい行に記述します。

const average = (arr) => {
  debugger;
  const _sum = sum(arr);
  const avg = _sum / arr.length;
  return avg;
};

任意で処理をすすめる

ブレークポイントで処理を止めた状態から、処理を進める方法を紹介します。Chorome DevTools 右上の3つの矢印ボタンを使用します。左から、ステップオーバー・ステップイン・ステップアウト になります。

それぞれ、どんなことをする機能なのか説明します。

また、⌘ + R でリロードを行うことで、最初にブレークポイントを設定した時に、処理を戻すことができます。

ステップオーバー

ステップオーバーは処理を1行分すすめます。その時、実行した処理に関数が存在していた場合でも、関数へのジャンブは行われません。

↑はステップオーバーのボタンをクリックした時の画像です。sum 関数が実行されていますが、sum 関数にはジャンプせず、次の行に青い背景が写っているのがわかるかと思います。

ステップイン

ステップインは処理を1行分すすめます。の時、実行した処理に関数が存在していた場合は、関数へのジャンプを行います。

↑は最初に9行目にブレークポイントを設定して、ステップインをクリックした時の画像です。今度はステップオーバーの時とは違い、 sum 関数の内部にジャンプを行っています。関数呼び出しのない行では、ステップオーバーとステップインは同一の挙動となります。

ステップアウト

ステップアウトは、現在の行の呼び出し元の関数の処理が終わるまで実行し、関数を抜けます。

9行目でステップアウトをクリックすると↓のようになります。

average 関数が実行されていた14行目の処理が終わった状態になり、15行目にジャンプしています。

ステップオーバー・ステップイン・ステップアウト の3つの機能をうまく使い分けることで、処理を進めながらデバッグを行います。

変数の確認

ブレークさせた状態で変数を確認したいという場面があると思います。変数を確認する方法には以下の方法があります。

  • 代入された変数は、右側に値が表示されるため、それを確認
  • 変数にカーソルを当てる
  • Scopeパネルを開く
  • Watchパネルに変数名を入力する
  • Consoleタブで変数名を入力する

この中から、3つ目と4つ目の "Scopeパネルを開く" と "Watchパネルに変数名を入力する" を解説します。

Scopeパネルを開く

DevTools のSourcesタブの右側にいくつかパネルがあります。その中の1つにScopeという名前のパネルがあります。Scopeパネルは、処理が止まっている箇所での変数の値を確認することができます。

arravg_sum の値が確認できていますよね。Scopeパネルでは、現在の行で参照できる変数がすべて確認できます。

また、現在9行目のプログラムは実行されていない(ブレークポイントは指定した行は実行されない)ため、 _sumundefined となっています。ステップオーバーで次の行に処理をすすめると、配列の数値の合計である 15_sum に代入されます。

また、Scopeパネルでは、変数の状態を変更することもできます。試しに配列の値を 1100 に変更してみたいと思います。

配列の値を書き換える

この状態で、ステップオーバーすると、 _sum の値が 114 になります。

変更した値が計算結果に反映された

このように、実際のコードに手を加えることなく、変数の値を変えながらデバッグすることができます。その結果、効率的にデバッグをすることができるようになります。

Watchパネルに変数名を入力する

Scopeパネルは、任意の変数を記述することで、その変数の現在の状態を確認できます。例えば、 avg を指定した例が下記になります。

最初は何も入っていないため、 undefined ですが、2回ほどステップオーバーをクリックすると、↓のように計算結果が代入されます。

他にも、 localStorage に入れているデータを取得し、表示させることもできます。Scopeタブで変数を確認することもできますが、大規模なコードになると、変数やオブジェクトの数が多くなるため、一つの変数の値を追うのが困難になります。そんな時、この機能を使用することでより厳格に変数を管理することができます。

Call Stack

Call Stack というパネルでは、どういう関数を経由して現在の行が呼ばれているかが確認できます。こういった、どういう関数を経由して現在の行が呼ばれているかを関数のコールスタックと呼びます。

Call Stackパネルでは、1番上に現在実行されている関数が表示されています。現在は average 関数が表示されています。例として、ステップインを行い、 sum 関数に入ってみます。

Call Stackパネルに、 sum 関数が追加されました。さらにステップインを行うと、 reduce メソッドを指定している無名関数に入ります。コールスタックでは無名関数は anonymous と表示されます。

このように、関数を実行するたびにスタックとして積まれていきます。また、Call Stackパネルの関数名のところをクリックすると、該当の関数にジャンプできます。今回は単純な例ですが、コードが複雑になってくると、処理の順番はデバッグする上で重要な手がかりになることもあります。

まとめ

今回は、ブレークポイントを使用したデバッグについてまとめました。Sourcesタブを活用すれば、JavaScriptのデバッグを非常に楽にすることができます。コーディング力に目を奪われて軽視しがちですが、エンジニアにとってデバッグは非常に大切な能力の1つになります。ぜひ使えるようになっていただけたら幸いです。

参考文献


関連記事

この記事のハッシュタグ から関連する記事を表示しています。

「エミュレートとメディアクエリ検証」Chrome DevTools Tips集 #1

最新記事

カテゴリー

アーカイブ

ハッシュタグ