JavaScript,jQueryの爆速コーディング、デバッグ方法論の勧め～実践向け逆引き(windows,chrome向け)～

※2017/4/21にオンロード時のデバッグ方法8を追記しました！

こんにちは！エイチーム引越し侍の加藤です！

みなさんJavaScript書いてますか？

`console.log`めっちゃ使うよねーって人は目からうろこのデバッグ方法を、
ケース毎に紹介していこうと思います。(僕は`console.log`使いません)
サーバーにデバッグ用のコードをアップロードすること無いので、
消さずに意図に反してリリースしてしまう危険性がないのもお勧めです。

# 前提知識
<kbd>F12</kbd>で出てくるデベロッパーツール(Elements, Console, Source, Network)の知識
<kbd>Ctrl+Shift+F</kbd>で外部ソース(js,css)に対して一括検索ができる
HTML、CSSはElementsから直接修正⇒確認ができる
jsはSourceから直接修正できる(<kbd>Ctrl+S</kbd>で保存したらその状態で実行できる)
jsはブレークポイントをおいてデバッグができる
consoleでjsが実行できる(＆変数名だけでその中身が見れる)
ajaxでとってきた値はNetWorkで見れる
ユーザエージェントをスマホにできる

ここら辺がわかっている方にさらに有用な情報をお届けできればと思います。

# デバッグ逆引き
1. このボタン押したら何が動くの…？(この要素に紐付いているイベントなんなの？)
2. いつのまにこの要素が変わったの…？
3. ブレークポイント置いてみたけど何回も通る箇所だからcontinueめんどくさい…
4. ここのif文もし変数がこの値になったらどんな挙動になるの…？
5. この関数が呼ばれてるのはわかってるんだけど、どこから呼ばれたの？
6. 配列の中身が見たいんだけどいちいち開くのめんどくさい…表形式で表示できたら…
7. javascriptのエラーがユーザ側で起きてるっぽいんだけど再現できない…
8. オンロード時のデバッグただのブレークポイントだとめんどくさい…

# 1.このボタン押したら何が動くの…？(この要素に紐付いているイベントなんなの？)
EventListenersを見ましょう！

引越し侍ではピアノ運送一括見積りサービスを運営しています。
スマホサイトでは郵便番号を入れて、住所自動入力というボタンを押すと
都道府県、市区町村、町域が自動で入力されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/146642/4702d305-3435-144e-3341-d76d86715ad9.png)

ただjQueryを使っていると

```js
$('p').click(function(){
     hogehoge;
});
```
だったり、

```js
$('p').on('click',function(){
     hogehoge;
});
```

だったりいろいろ書き方ありますよね
<kbd>Ctrl+Shift+F</kbd>で`click`で検索かけたら自前の関数名がいっぱい引っかかってめんどくさかったりしませんか？

そんなときにHTMLの要素にどんなイベントがついているのかを一発で確認する方法があります。

Elementsで見たい要素を選択して右側に現れているStylesとかが表示されているタブの2つ右くらいに
EventListenerというタブがありますよね

※jQueryなどで設定している場合はFramework listenersというチェックボックスにチェックを入れてください
![image](https://qiita-image-store.s3.amazonaws.com/0/146642/26858b1a-995d-73f9-58fc-d241b521e274.png)


ほーら`click`したときにどの外部ファイルのどの行が動くのか丸わかりですよ！
しかもリンクをクリックでソースにジャンプできます。


#2.いつのまにこの要素が変わったの…？
ElementsからBreak onを使おう！

実は先ほどの画面では郵便番号を入れて、住所自動入力すると、
都道府県を取得
⇒選択された都道府県に紐付くすべての市区町村をセレクトボックスに挿入、該当の市区町村を選択
⇒選択された市区町村に紐付くすべての町域をセレクトボックスに挿入、該当の町域を選択

という少し複雑な処理になっていました。
なので、どのタイミングで町域が変わるんだ…！ということを確認するのに、ブレークポイントを置いて確認するのがめんどくさかったです。

```js
$("#hogehoge").append('hogehoge')
```

って感じで値を変更してくれていればまだ追いやすかったんですが、

```js
id = "#hogehoge"

中略

function bar (id) {
  $(id).append(option);
}
```

のようになっていてかなり到達するのに時間がかかりそうな感じです。

そこで使うのがBreak on
Elementsから要素を選んで右クリックで図のようにBreak onというのが選べます。

![image](https://qiita-image-store.s3.amazonaws.com/0/146642/6adb980c-e5bd-d81d-29d0-e087082c70ae.png)

今回はsubtree modificationを選んで、住所自動入力ボタンを押します。
このときjQueryのコードにいざなわれるかもですが、step out等で抜け出してください。

今回の該当のコードの1つである

```js
$(id).children().remove();

中略

$(id).append(option.attr({ value : 'ほげほげ' })
```

に簡単にたどり着くことができました。

#3. ブレークポイント置いてみたけど何回も通る箇所だからcontinueめんどくさい…
`if`文を追加して、`debugger`を記述しよう！(ブレークポイントでも可)

`console.log`なんて無かった時代は`alert`でデバッグしてたって聞いて、
何回もOKを押さないといけない状況を想像して、爆笑しました。

この条件のときの処理が見たいんだよ！ってときありますよね。
そんなときはSourceから

```js
if (condition) {
  debugger;
}

後ほど続くconditionのときに見たい処理
```

と記述しましょう。(<kbd>Ctrl+S</kbd>で保存)`debugger`のところにブレークポイントを置いても同じです。

#4. ここの`if`文もし変数がこの値になったらどんな挙動になるの…？
ブレークポイントで止めてConsoleから書き換えてしまおう！

エラー処理とか書いてみたもののそのエラーケースを発生させるのめんどくさいなってことありませんか？

```js
if (text == null) {  // 全然このパターン起こせない
　エラー処理!!!
}

```

そんなときはエラー処理の上にブレークポイントを置いてそこでとまったときにConsoleから

```js
text = null
```

とたたきましょう。
もう一度ドラッグするなどしてフォーカスすると変数の中身が変わっています。(Consoleで`text`とたたいても確認できます。)

#5. この関数が呼ばれてるのはわかってるんだけど、どこから呼ばれたの？
`console.trace`を使おう！

ある関数がいろんなとこから呼ばれすぎて、この処理のときはどこから呼ばれているんだろう…
と逆からたどりたくなることありますよね。

そんなときはSourceからその関数の中で

```js
console.trace();
```

と記述しておきましょう。(<kbd>Ctrl+S</kbd>で保存)

```
console.trace
hogehoge   @ hoge.js:10
fugafuga   @ fuga.js:3
```

といった感じでConsoleに表示されます。

#6. 配列の中身が見たいんだけどいちいち開くのめんどくさい…表形式で表示できたら…
`console.table`を使おう！

ブレークポイントを置いて配列の中身を見ようとしたら

![image](https://qiita-image-store.s3.amazonaws.com/0/146642/9e9c9f8c-c95d-f87d-6da3-67b5df5e9bbc.png)

いちいちこんな感じで開いていかないと見れないのがうっとうしいですよね。
そんなときは`console.table(hoge)`とConsoleで打ってみましょう

![image](https://qiita-image-store.s3.amazonaws.com/0/146642/7a539079-5f84-9582-c286-d9241a57fd4f.png)

見やすい感じで表示されました！

#7. javascriptのエラーがユーザ側で起きてるっぽいんだけど再現できない…
ユーザがエラーを起こしたときの状況をサーバーに送ってもらおう！

ユーザは予想外の行動をしたり、
ユーザーエージェントとかデバイスとかパターンがありすぎて、
クライアントから苦情が来たりしてでも再現できなくて詰んだ…

って状態ってたまにありませんか？
そんなときは

```js
window.onerror = function(msg,url,line){
  $.ajax({
    ...中略...
  });
}

とか

if (condition) {
  $.ajax({
    ...中略...
  });
}
```

とかいうデバッグ用のコードを仕込んで、
データをajaxでサーバーに送って、再現の方法を直接ユーザに教えてもらうのもアリかもしれませんね。
リリースが必要ですが。

#8. オンロード時のデバッグただのブレークポイントだとめんどくさい…
条件付ブレークポイントを使おう！

Sourceからjsを修正して

```js
if (hoge) {
  debugger;
}
```

とか書いたけど<kbd>F5</kbd>でリロードしたら消えるやん…
っていう経験ありますよね。
そんなときは条件付ブレークポイントを使いましょう。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/146642/5cde2c54-6b0e-5246-62ba-047052b515ee.png)

Sourceの行数のところで
Add conditional breakpointを選択して

![image.png](https://qiita-image-store.s3.amazonaws.com/0/146642/3ae28e53-e69d-99bf-26e1-5061738c38bc.png)

こんな感じで条件だけを記述してあげれば条件に合致したときにとまります。


以上です。
いかがでしたか？

こんなときにこれを使えばいいよってわかりやすい記事があんまりない気がしたので
まとめて見ました。
これでみなさんのデバッギングが少し楽しく爆速になってもらえれば幸いです。

# 追伸
株式会社エイチーム引越し侍では、一緒にサイト改善をしてくれるWebエンジニアを募集しています。エイチームグループのエンジニアとして働きたい！という方は是非、以下のリンクから応募してください。
皆様からのご応募、お待ちしております！！

> [エイチームグループ採用サイト（Web開発エンジニア職）](http://hikkoshi.a-tm.co.jp/recruit/request.php?ea=ktqiita_bakusoku)