そもそもトレースってどうしたらいいのか分からない
JavaScriptでトレースを行う手法について知りたい
効率の良いトレース方法を学習したい
JavaScriptのプログラムで誤りやバグの発見をするため、デバッグ手法の1つとしてトレースを行うことがあります。
JavaScriptは一般的なプログラムだけでなく、DOM要素を制御することもあるためどのようにトレースをしたら良いのか悩むことも少なくないでしょう。
こんにちは!ライターのマサトです。
この記事では、初心者でも今日からトレースを実践することができる方法について分かりやすく解説していきますので、ぜひ最後まで読んで理解を深めて頂ければ幸いです。
この記事はこんな人のために書きました
- トレースとは何かを学びたい方
- JavaScriptでトレースを行う手法について知りたい方
- 効率よくトレースを行う方法を学習したい方
「トレース」とは?
トレースはプログラムの誤りがどこにあるのかを発見するために、順を追って1つずつ順番に実行して状態を確認していくデバッグ手法の1つです。
JavaScriptでは、このトレースを行うためにさまざまな機能やツールが提供されており、これらを活用することで効率よく作業を進めることができます。
一般的には次のような方法が利用できます。
- consoleオブジェクトで提供されているメソッドを利用
- ブラウザに搭載されているDev Toolsを利用
- イベント処理用のメソッドを利用
上記内容について、1つずつ詳しく見ていきましょう!
consoleオブジェクトでトレース
この章では、JavaScriptが標準で提供しているconsoleオブジェクトを利用したトレース方法を見ていきましょう。主に、ロギングやトレースメソッドの利用について学んでいきます。
console.logによるロギングについて
JavaScriptのトレースにおいてもっとも基本的な方法として使われるのがconsole.log()メソッドでしょう。
ソースコードの中に挿入することで、変数やオブジェクトの中身を出力させてどのように状態が変化していくのかを把握するのによく使われます。
次のサンプル例を見てください。
let result = 0; for(let i=0; i<10; i++) { result += i; console.log(result); }
実行結果
0 1 3 6 10 15 21 28 36 45
この例では、for文の繰り返し処理の中にconsole.log()を挿入して、意図している通りに計算処理されているかをトレースしているわけです。
つまり、状態を確認したい箇所に随時console.log()を挿入していくため、あとで削除する必要がある点は忘れないようにしましょう。
console.traceによる関数のトレース
複数の関数を経由している場合、どこの関数と関連があるのか分かりづらくなりがちです。ソースコードの量が増えてくるとなおさら問題になりやすく、バグを発見するのも一苦労です。
そこで、consoleオブジェクトにはtraceメソッドが提供されており、関連している関数をすべて抽出できるようになっているのです。
次のサンプル例を見てください。
function test1() { function test2() { console.trace(); } test2(); } test1();
この例ではconsole.trace()を実行することで、どの関数を経由しているのかをログに出力してくれていますね。つまり、関数test1()を経由してtest2()の中でconsole.trace()が実行されていることを意味しているわけです。
他にもconsoleオブジェクトには便利なメソッドが提供されているのですが、詳しくは次の記事で体系的にまとめているのでぜひ参考にしてみてください!
DevToolsでトレース
この章では、ブラウザに標準搭載されているDev Tools(開発者ツール)を利用したトレース方法について見ていきましょう。本記事ではChromeブラウザに搭載されているDev Toolsを使い、ブレークポイントの設定方法からステップ実行の使い方までを学んでいきます。
ブレークポイントの使い方
Dev Toolsを使ってトレースを行うための基本的な使い方としては、ブレークポイントを活用する手法が一般的です。ブレークポイントを設定すると、プログラムを少しずつ止めながら実行することができます。
Dev ToolsのSourcesタブを開いてJavaScriptファイルを選択すると、ソースコードが表示されるので任意の行番号をクリックするだけでブレークポイントは設定できます。
この例では、36行目のconsole.log()にブレークポイントを設定したので、プログラムはこの箇所でストップしてくれるというわけです。
もちろん複数箇所のブレークポイントを設定できるので、確認したい箇所を随時ストップさせながらトレースを行うことができるのです。
ステップ実行によるトレース
ブレークポイントを設定したら、さらにステップ実行によってプログラムの中身がどのように変化しているのかも確認してみましょう。
先ほど36行目にブレークポイントを設定しましたが、その右側にあるパネルではconsole.log()で出力している変数iの値を確認することができます。
Watchパネルに変数の値が出力されるようになっており、ステップ実行ボタンをクリックするたびに値もリアルタイムに変化するようになっています。
この機能を使えば、わざわざソースコードにconsole.log()を記述しなくても変数の状態を確認することができるようになるので、あとでconsoleの記述を削除しなくても良くなるわけです。
イベント処理をトレース
この章では、Webページに埋め込まれたイベント処理をトレースするための確認手法について見ていきましょう。主に、Dev Toolsで利用できるAPIとJavaScript側で制御できるDOMの監視方法について学んでいきます。
コマンドラインAPIを活用する方法
Chromeブラウザに搭載されているDev ToolsにはさまざまなAPIが提供されているのですが、なかでもイベント処理を検出できるmonitorEvents()メソッドは大変便利です。
これはConsoleタブから直接メソッドを入力することで利用できるのですが、特定のイベント処理が実行された時にそのイベントオブジェクトをログとして出力することができます。
例えば、Webページに配置されたボタンをクリックした時にイベントオブジェクトを取得したい場合は次のように記述します。
monitorEvents(document.body, 'click');
ボタンをクリックするたびに以下のようなオブジェクトを出力することができます。
ただし、この状態だと実はボタン以外の箇所をクリックしても同じようにイベントオブジェクトを検出してしまいます。なぜなら、document.bodyを対象としているのでWebページ全体を検出することになるからです。
そこで、任意のボタンだけを検出するようにしたい場合は対象のDOM要素を取得する方法があります。
例えば、次のようなHTMLがあるとします。
【ボタン1】だけのクリックイベントを検出したい場合は次のようにDOMを取得して設定すれば良いのです。
const div = document.getElementById('div'); monitorEvents(div, 'click');
これで【ボタン1】以外をクリックしても反応しなくなるわけです。
MutationObserverを利用したDOMの監視
次に、JavaScript側でDOM(HTML)要素の変更を検出できるメソッドをご紹介しておきます。これは、プログラムで動的にDOM要素を変更・修正するのを監視してくれるので、いつどのタイミングでDOMが変化しているのかをトレースするのに役立ちます。
利用するのはMutationObserverで次のように記述します。
const observer = new MutationObserver( () => { console.log('DOMが変更されました!'); })
インスタンスを作成する際に、オプションとして引数にDOMの変更を検出した時に実行する処理を記述します。
あとはMutationObserverを起動させておけば完了です。
const config = { attributes: true, childList: true, characterData: true }; observer.observe(div, config);
configに最低限オプションとして設定しなければいけないプロパティだけを記述しています。observe()メソッドの引数に対象となるDOM要素とconfigを設定します。
div要素へ動的にPタグを次のように挿入してみましょう。
const div = document.getElementById('wrap'); div.innerHTML = 'サンプルテキスト
';
すると、コンソールログにMutationObserverで設定した文字列が出力されるようになります。つまり、DOMの変更を検出して指定した処理が実行されたというわけです。
このメソッドを利用すれば、複雑なDOM変更処理がどのように実行されているかを把握することができるので便利です。
まとめ
今回は、JavaScriptでトレースを行うための手法についていくつか例を挙げながら学習しました。
最後に、もう一度ポイントをおさらいしておきましょう!
- ソースコード内にconsole.logを挿入することで状態を把握する
- Dev Toolsを利用すれば状態の把握やイベント処理の確認ができる
- DOMの変更を検出するにはMutationObserverを利用する
上記内容を踏まえて、ぜひ自分でもプログラミングに取り入れて活用できるように頑張りましょう!