デバッガを使ってJavaScriptのコールバックを理解する

## はじめに
今回は、デバッガを使ってJavaScriptのコールバックとコールスタックを理解する方法について書いてみました。

## この記事の対象者
- JavaScriptの基礎学習を終えている方
- コールバックがいまいち理解できない方
- JavaScriptのデバック方法がよくわからない方

尚、詳しい解説は今回は省略しています。

## 開発環境
```
mac OS: Ventura 13.3.1
Visual Studio Code
Chrome version 113
```

## コールスタックとは何か
JavaScriptの実行環境では、コールスタックというメカニズムが機能しています。コールスタックは、実行中の関数の情報を一時的に保存する場所です。関数が呼び出されると、その関数はスタックの一番上にプッシュされます。
  
そして関数の処理が終わったら、スタックからポップされます。この一連の流れによって、関数がどの順番で実行されるべきかが決まります。これが最後に入れたものが最初に取り出される（Last In, First Out：LIFO）という原則を実現しています。

## コールバックとは何か
コールバックは、ある関数が完了した後に呼び出される関数のことを指します。特にJavaScriptでは、非同期処理を行う際にコールバック関数をよく使用します。たとえば、setTimeout関数は指定した時間が経過した後にコールバック関数を実行します。また、サーバーからデータを取得する際にも、データの取得が完了した時点でコールバック関数が実行されます。
  
分かりにくいので、図を使ってデバックの流れを説明していきます。

## デバックにてコールスタックを学ぶ
### 1: まずHTMLとJavaScriptのファイルを準備します。

#### HTML
``index.html``
![スクリーンショット 2023-05-20 9.54.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/c46e695b-aa4c-472e-b956-86239a49137d.png)

#### JavaScript
``app.js``
![スクリーンショット 2023-05-20 9.31.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/b450b825-5a6d-68fe-c649-0a8fd3477060.png)

**このコードの説明**
このJavaScriptコードはピタゴラスの定理をチェックするための簡単なプログラムです。

1. ``'use strict';``
    この行はstrictモードを有効にします。strictモードでは、JavaScriptの一部の機能が制限され、より厳密なエラーチェックが行われます。これにより、開発者は予期しないエラーやバグを早期に発見することができます。(省略可)
1. ``const multiply = (x, y) => x * y;``
    この行は2つの数値を乗算する矢印関数（アロー関数）multiplyを定義しています。
1. ``const square = (x) => multiply(x, x);``
    この行は与えられた数値の二乗を求める矢印関数squareを定義しています。これはmultiply関数を使用して与えられた数値を自分自身と乗算しています。
1. ``const isRightTriangle = (a, b, c) => {...}``
    この行は3つの数値が直角三角形の3辺の長さを表しているかどうかをチェックする矢印関数isRightTriangleを定義しています。これはピタゴラスの定理を使用しています（直角三角形において、直角をはさむ2辺の長さの2乗の和は斜辺の長さの2乗と等しい）。
1. ``isRightTriangle(3, 4, 5)``
    この行はisRightTriangle関数を実行しています。ここでは3、4、5という値を関数に渡しています。これらの数値は直角三角形の辺の長さを表しており、そのため関数はtrueを返します。つまり、3、4、5はピタゴラスの三つ組です。



### 2: 上記のプログラムをデバッガーを使用して追跡する
※ HTMLをブラウザで表示しておいてください。

(1): 開発者ツールを開く

[開発者ツールについては MDN web Docs__ を参照下さい](https://developer.mozilla.org/ja/docs/Learn/Common_questions/Tools_and_setup/What_are_browser_developer_tools)

このような画面になりますので、``Source``をクリックしてください。
![スクリーンショット 2023-05-20 9.32.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/c2e3f744-38d5-dc67-4779-ca0eadfe64d7.png)

すると、先ほど作成した``app.js``を開発者ツールから確認できます。
![スクリーンショット 2023-05-20 9.32.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/af175bcb-4f28-a369-4707-d63510b1b516.png)

(2): ブレークポイントを貼る
行数のところをクリックするとブレークポイントを貼ることができます。これはデバッガーといって、JavaScriptが実行される時に動きを止めてくれます。

![スクリーンショット 2023-05-20 9.33.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/79f8cf5e-134a-47ab-f5eb-d41292842798.png)





(3): 再読み込みをかける
![スクリーンショット 2023-05-20 9.34.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/cfc7473a-c050-6dd2-157f-61a5b359147d.png)

再読み込みをかけた後、ブレークポイントを張ったところで実行を止めることができます。
行数の横をクリックすると、図のように青いものが出てきて、ブレークポイントを貼ることができます。
JavaScriptが実行する際に、そのポイントで止めることができます。

コードを書いたが思ったように動いてくれない時、指定した場所でコードが止まるようにして調べたい場所の状況を調べることができます。

分かりやすいように、`isRightTriangle(3, 4, 5);`の前後に、`console`で表示されるようにしておきます。

では再び読み込みます。
13行目の関数呼び出し演算子をブレークポイントに指定したので、以下のように13行目で止まっています。

![スクリーンショット 2023-05-20 15.04.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/e8488db9-eeea-63a5-0a2f-637d04409526.png)

`Step into next function call`を実行して1行ずつ処理を行なっていきます。
(画面でいうと左端の下の　↓　をクリックしてください)

そうすると、8行目に進みます。
図のように呼び出された関数に移動するのがわかると思います。引数で受け取った値も表示されてますね。

![スクリーンショット 2023-05-20 9.42.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/afdaf61c-b799-d5f7-a15b-63ea99a2a8df.png)

次に`Step into next function call`を実行すると、さらに呼び出された関数に移動しているのが分かります。(図 5行目)
この例だと、8行目のsquare(a)を呼び出した後に、5行目に移動して、`multiply(x, x)` を呼び出してますね。

![スクリーンショット 2023-05-20 9.42.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/7a73d78f-86a8-6cc9-2531-3b189a9026ad.png)

そして、呼び出された3行目で計算されて、、、

![スクリーンショット 2023-05-20 9.42.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/81902744-c597-8a71-a047-a997ff2982b3.png)


計算された値が5行目に返され、7行目のsquare(a)`にcall back`されるということになります。


![スクリーンショット 2023-05-20 9.48.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/449b14d8-5ff1-cbc5-7996-6b66bd7b2cb8.png)


`square(b), square(c)`も同じ感じで処理を行なっていきます。


![スクリーンショット 2023-05-20 9.48.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/0461ca4f-a140-45a4-b3b4-d84ef10b3512.png)

右下の図の`Scope`で受け取った引数の数値と`return`された結果が分かります。


![スクリーンショット 2023-05-20 9.49.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2401767/ae391e2f-9241-608d-d063-5ddfeafda924.png)


こんな感じでコールバックのデバックを行うことで、実際にコールバックがどういった処理を行なっているかが分かります。