🎃

JavaScriptの挙動を見る①<実行コンテキスト,コールスタック,ホイスティングetc...>

2023/08/20に公開

JavaScriptの基礎知識をつけよう

今回はTypeScriptやReactを触る前に!!JavaScriptについてしろう! 
ということで、JavaScriptの知識について記述していきます。

何回かに分けて書きたいなと思います。今回は以下の内容になります。

1. JavaScriptとは
 - 歴史、
 - ECMAScriptと、その関係性
2. JavaScriptが実行される仕組み
 - 実行コンテキストとは
 - コールスタックの仕組み
 - ホイスティングとは
 - モジュール(Modules)について知る
 - DOMについて(入門)
3. JS前提知識 (変数、関数、オブジェクト)

JavaScriptとは:

  • ECMAScriptの仕様に基づいて実装されている、プログラミング言語。
  • スクリプト言語であり、実行時にプログラムを解釈する。(動的型付け)

    スクリプト言語とは
    コンパイルの代わりに実行時にプログラムを解釈する言語。

  • 環境によって使える機能が変わる。
補足: 言語の種類(コンパイラ?スクリプト??)

大きく分けると、主にコンパイル言語とスクリプト言語の2つです。
以下のように、一般的な特徴をまとめたtableを作成してみました。

コンパイラ言語 スクリプト言語
概説 プログラムをコンパイルして実行可能ファイルを生成する言語 コンパイルの代わりに実行時にプログラムを解釈する言語
解釈/コンパイル コンパイル 解釈
代表例 C、C++、Java、Swift、Kotlin Python、Ruby、JavaScript、PHP、
Perl、Shell Script等
実行速度 高速 低速
デバッグ 難しい 容易
開発速度 遅い 速い
コード量 多い 少ない
メモリ使用量 少ない 多い
長所 実行速度が高速 開発速度が速い
短所 デバッグが難しい
コード量が多く、開発に時間がかかる
ポータビリティに欠ける
(OSやCPUに依存することがある)
実行速度が遅い
メモリ使用量が多く、
大規模なプログラムには向かない
コードが読みにくい場合がある

この二つの処理の違いは..."機械語への翻訳仕方の違い"

過去にここは詳しく記事にしたので、気になれば見てください!

https://zenn.dev/airiswim/articles/7231c9b5e61545

JSができた経緯とECMAScriptについて

1990年代:

  • Netscape Navigaterというブラウザがあった。
    ここによって開発されたプログラミング言語が、JavaScript。
  • その頃同様に人気が出てきてライバルだったのが、
    InternetExproreというブラウザ。
    MicroSoft社が開発しているブラウザで,Windowsの配布に伴ってシェアされたが、
    ここで開発されたのは、JScript。
  • この2つの言語には互換性がなく、考え出されたのが、ECMAScript。

ECMAScript:
JavaScript言語のコアな部分をECMAScriptとして仕様策定。

このEcmaScriptの登場により、ブラウザ間での仕様を統一できた。

補足:実行環境の差で使える機能が変わるJavaScript

現実、ECMAScriptの仕様を元に作成されたプログラミング言語で
メジャーなものは、JavaScript以外ないため、
ECMAScriptは、JavaScriptの一部の仕様とも言える。
=> 一部ということは、これ以外にも環境によって持っている機能が違う。
実行する環境によって使える機能が変わってくる。

[■ ブラウザ上のJavaScript]

  • Web APIs:
    JavaScriptからブラウザの機能を使うAPI。
    ブラウザにはさまざまなWebAPIも提供されており、
    例えば fetch を使用してサーバーからデータを取得したり、
    localStorage を使用してデータをローカルに保存したりすることができる。

  • DOM操作:
    これもWEB APIの一種。
    ブラウザ上のJavaScriptでは、Document Object Model(DOM)を
    操作するためのAPIが提供される。
    これにより、HTML要素を動的に変更したり、イベントを処理したりすることが可能。

DOMについてはのちに詳しく書きます。

const button = document.querySelector("#myButton");
button.addEventListener("click", () => {
     // ボタンがクリックされたときの処理
});

[■ Node.js上でのJavaScript]

  • CommmonJS(ファイル操作)
    CommmonJSとは、モジュールを管理する仕組み。これを使用可能。
    Node.jsでは、ファイルを読み書きするためのファイルシステムモジュールが提供されます。これにより、サーバーサイドでファイルの操作を行うことができます。

ブラウザとJavaScriptエンジン

JavaScriptエンジンとは、
JavaScriptコードを実行するための欠かせないソフトウェアコンポーネント。
これは与えられたJavaScriptコードを解釈し、実行可能な形式に変換して実行する役割を果たす。

JavaScriptエンジンにはさまざまな種類がありますが、
現在最もシェアが高いのはV8エンジン。

JavaScriptエンジン 対応する主要なブラウザ
V8 Google Chrome
SpiderMonkey Firefox
JavaScriptCore Safari
ChakraCore Microsoft Edge

これにより、異なるブラウザはそれぞれ専用のJavaScriptエンジンを使用して、
Webページ上で動作するJavaScriptコードを処理する。

JavaScriptは、単にWebページ内の装飾や動的な機能を提供するだけでなく、
ブラウザからさまざまなサービスや情報にアクセスする手段としても利用される。
このため、JavaScriptからブラウザにアクセスするには、
Web APIと呼ばれるインターフェースを使用している。

Web APIは、以下のような機能を提供.

  • DOM操作:
    Webページ上の要素やコンテンツにアクセスして操作するためのAPI。
  • XMLHttpRequestやFetch API: サーバーとのデータの送受信に使用されるAPI。
  • Geolocation API: ユーザーの位置情報にアクセスするためのAPI。
  • Canvas API: グラフィックスや画像処理を行うためのAPIなど。
補足:APIってなんだ??

Application Programming Interfaceの略で、
ソフトウェアやアプリケーションの機能を外部から呼び出し、_
利用するためのプログラムの集合体。
つまり、APIは
プログラマーがソフトウェアやアプリケーションを作成する際に使用される、
他のプログラムやサービスとのインターフェースを提供する技術

これをもっと簡単にいうなら、
プログラマーが作成するソフトウェアやアプリケーションと、
他のプログラムやサービスをつなぐための技術

ブラウザについて過去に記事を書いたので、興味のある方は見てください(^^)
https://zenn.dev/airiswim/articles/71cfd48cba418b

JavaScriptの実行を詳しくみる:-スクリプトが実行されるまで

JavaScriptコードが実行されるまでの流れは、以下のようになります。
ちょっと六段階で書いてますが、ながかったので、タブにしたので、見てください!笑

スクリプトが実行されるまで

1. ソースコードの解析:
JavaScriptエンジンは、与えられたソースコードを解析してトークンに分割し、
文法的に正しいかどうかをチェックします。
2. 実行コンテキストの作成:
実行コンテキストとは、コードを実行するために必要な環境情報やデータを保持するコンテナ。
スクリプト全体や関数の呼び出し毎に、新しい実行コンテキストが作成されます。
3. 変数の初期化:
変数の宣言(var や let、const)や関数の宣言が実行コンテキスト内で特定され、
変数環境に格納されます。ただし、代入はこの段階では行われません。
4. コードの実行:
実際にコードが実行されます。式や文が評価され、必要に応じて変数に値が代入されたり、
関数が呼び出されたりします。
5. ステップ3と4の繰り返し:
コードの実行が進むにつれて、実行コンテキストはスタックに積まれ、新しいコンテキストが作成されます。
関数呼び出しやスコープの変更に応じて、実行コンテキストが切り替わります。
6. コードの終了と実行コンテキストの削除:
コードの実行が終了すると、対応する実行コンテキストはスタックから取り除かれます。
これによってメモリの解放が行われます。

この流れの中でも大事な、実行コンテキストについて解説します。

実行コンテキストについて理解しよう

用語補足:
直訳 >Context:前後関係、脈絡、コンテキスト、状況、環境
ここでの実行コンテキスト
コードを実行する際の文脈・状況
= コードがどのような状況で実行されているのかということ

実行コンテキスト

実行コンテキストには3種類がある。

実行コンテキストの種類 説明
グローバルコンテキスト スクリプト全体の実行コンテキストであり、
ブラウザでは window オブジェクトがグローバルオブジェクトとなる。
関数コンテキスト 関数が呼び出されるたびに生成され、
その関数内での変数やスコープ、this の値を管理。
evalコンテキスト eval 関数によって実行されるコードの実行コンテキスト。
一般的には避けるべき。
evalという変数はもうすでに非推奨になっている.

しかし、evalという変数は記述した通り、もうすでに非推奨になっているので、
一旦考えず、よく登場する上記二つを。

グローバルコンテキスト 関数コンテキスト
使えるもの - 実行中のコンテキスト内の変数と関数
- グローバルオブジェクト
- this
- 実行中のコンテキスト内の変数と関数
- arguments
- super
- this
- 外部変数

例を用いてわかりやすくすると...

index.html
<!DOCTYPE html>
<html lang="en">
<head>
   :
</head>
<body>
   :
    <script src="main.js"></script>
</body>
</html>

htmlファイルから、<script src="main.js"></script>でmain.jsを読み込んでいる。
このmain.jsの直下に書かれたコードが、実行される環境のことをグローバルコンテキストと呼ぶ。
スクリプト全体の実行を管理する。
以下のように、グローバルコンテキスト(今回で言うと、main.js)内で変数や関数が使える、
ということもここで理解できる。

main.js
// グローバルコンテキスト
const val = "I'm Variable";
function fn(){
}
fn();

関数コンテキストというのは、"関数が実行される際に生み出されるコンテキスト"と言ったが、
上記の例だと、関数fnが実行されているが、このこの関数のナビブロック{}の中が、
関数コンテキスト
という。

そしてその中で使えるのは、
実行中のコンテキスト内の変数と関数argumentssuperthis外部変数

main.js
const val = "I'm Variable"; // 外部変数(関数の外で宣言された変数のこと。)
function fn(){
// 関数コンテキスト!
console.log(this,arguments,val)
}
fn();

Consoleで確認するとこのようにできている。

コードを追跡する仕組み: コールスタック(Call Stack)

英語直訳> Stack:積み重ね

実行中のコードが辿ってきたコンテキストの積み重ねのこと。
どの関数がどの順序で呼び出されたかを追跡するデータ構造である。
=> JavaScriptは関数呼び出しが発生するたびに、
その関数をコールスタックにプッシュし、関数が終了したらポップする。
= 現在実行中の関数がわかるようになっている

main.js
function fn1() {
}
function fn2() {
    fn1();
}
function fn3() {
    fn2();
}
fn3();

一連を画像にしてみた。

画像が細かいので、細分化したら...

細分化して説明すると...

まずは、前のコンテキストでも説明した通り、グローバルコンテキストが生成される。

その中の関数が、順番に実行され、CallStackとして積み上がっていく。
ここでもう一度コールスタックの意味を確認.
"コンテキストの積み重ね"だ。

順番に実行され積み上がっていき、、、

現在実行中の関数は一番上に来るため、実行中関数がわかるようになっている

そしてコンテキスト実行され処理が終わると順番に消滅されていく。

コード実行しながら、developer toolで確かめてみよう。

developer toolのソースを選択し、fn3にブレイクポイントをおく。
そして画面をリロードする。(JavaScriptが実行される。)

匿名と書かれているのは、グローバルコンテキスト。
まずはグローバルコンテキストが実行されている。

のボタンで次に進めていきます。

このように続けていくと、積み上がっているのが確認でき、
ここのコールバックの説明の初頭で、
**"どの順序で呼び出されたかを追跡するデータ構造"**とも説明を書いたが
このように確認が可能なのです。

そして以下のように**範囲(Scope)**のところも開いて、
確認が可能です。

LIFO (Last In, First Out)

上記で話した、このようなコールスタックの仕組みを、LIFO (Last In, First Out) という。 
直訳すると、後入れ先だし
あとから積み上がったものが、先になくなる(消滅する)というコールスタックの仕組み。

ホイスティング(Hoisting)

コンテキスト内で宣言した変数や関数の定義を、コード実行前にメモリーに配置すること。
宣言の巻き上げともいう。

ここは先に例を行いながら解説を書きます。今回は関数で説明していく。
普通なら、このように関数を宣言して、あとから呼び出す

main.js
function fn(){
  console.log("関数は実行された!!!")
}
fn();

もちろんコンソールで確認すると、呼び出されたことが確認できる。

では、これが以下のコードのように、先に来たらどうだろう。

main.js
fn();
function fn(){
  console.log("関数は実行された!!!")
}

このようにしても、同じように呼び出され表示される。
この理由がまさに、ホイスティング(Hoisting)だ。

他の定義の仕方の場合、違う挙動になることがあるが、またのちに..

実行される前に、定義はすでにすべてメモリに登録されているためだ。

変数でもみてみよう。
変数は少し長いので、タブにしまいます。

ホイスティングで変数はどのようになっているのか。

変数3つの種類見てみます。

変数var

さっきと同じ容量で、先に持ってきてみよう

console.log(val);
var val = 1;

これでみてみると... Undefindとなっている。

どういうことかというと、
中ではこのようになっている。

var val; // 実際に描かれるわけではなく、宣言を見つけたらメモリを確保する。
console.log(val);
var val = 1;

実際に描かれるわけではなく、宣言を見つけたらメモリを確保する。
変数Valのメモリスペースを確保した状態で、undifindという特殊な値を設定する。
JavaScriptエンジンで自動的に行われている。
これは、var特有だ。

const、letだと...??

console.log(val);
let val = 1;

これでみてみると、このようなエラーが出る。

Uncaught ReferenceError: Cannot access 'val' before initialization..
Uncaught 参照エラー: 初期化前に 'val' にアクセスできない
bが初期化されていませんというエラーだ。
この原因は、メモリスペース自体は確保しているが、letの場合は、
先ほどのvarと違い、undefindの初期化が行われないためだ。constも同様だ。

こういう差もあり、現在はvarが非推奨になっているよ。

モジュール(Modules)について知る

英語直訳> module: 基本単位、基準単位

ソースコードを機能毎に分割してメンテナンスしやすくする仕組みのこと。
プログラム内で特定の機能や機能グループをまとめ、
再利用可能な単位として提供するための仕組み(単位) とも言える。
これ以外にもモジュール管理を行うものはあり、ESM(ESmodule)、CJS(CommmonJS)がある。

違いを理解する

まず簡単にtableで違いを。

特徴 / 形式 ESM (ES Modules) CJS (CommonJS)
構文 import / export require / module.exports
解決方式 静的解決 動的解決
同期/非同期読み込み 同期読み込み 動的なため非同期読み込み
エクスポート方式 名前付きエクスポートとデフォルトエクスポート オブジェクトとしてエクスポート
ユーザビリティ モダンな構文、非同期インポートをサポート Node.jsで初めて使用された形式
対象環境 ブラウザ Node.js

CJS(CommonJS)

CommonJSとは、サーバーサイドなどのウェブブラウザ環境外における、
JavaScriptの各種仕様を定めることを目標としたプロジェクトである。

NodeJS上でモジュールを管理する仕組みのこと。
**require / module.exports**を使用して、
モジュールの読み込みや外部ファイルへの露出を行う。

※過去にnpmとmoduleについてまとめたのでこちらも参照ください!

ESM(ESModule,ECMA Script Modules)

ECMAScriptの仕様に基づく、モジュール管理システム。
import / exportを使用。
主にブラウザ側で使用することになる。

`import` / `export`
  • ExportとImportは、両方ともJavaScriptでモジュールを扱うための構文です。
    MDN:Import
  • JSチュートリアル:ExportとImport
    ExportとImportについて知るにあたり、ESモジュールについても知っておきたいところです。

モジュール化するというは?
=> 大きなアプリケーションを小さな部品に分割することで、保守性や再利用性を高める開発手法のこと。

ESモジュールを使用するには...
  • モジュールの導入方法
  • ESモジュールを使用するには、以下のように、HTMLファイルのscriptタグにtype属性を指定する必要がある。
    (type属性に"module"を指定することで、ブラウザはこのファイルをESモジュールとして解釈するようになる)
<script type="module" src="main.js"></script>
  • src属性にはESモジュールを定義したJavaScriptファイルのパスを指定する。
モジュールかすることによるメリット

1. 再利用性が高まる

  • モジュール化することによって、小さな単位で機能を分割することができるため、
    同じ機能を複数の箇所で使う必要がある場合でも、同じモジュールを利用することができる。
    ( = 再利用性が高まり、効率的な開発が可能になります。)

2. 保守性が向上する

  • モジュール化することによって、コードの変更や修正がしやすくなる。
    = 大きなアプリケーションの場合、どこでどのような変更があったかを把握するのは困難だが、モジュール化することで変更箇所を明確にすることができるから。
    = 不具合が発生した場合も、モジュール化された小さな単位でテストやデバッグが行いやすくなる。

3. 名前空間(namespace)の衝突を防ぐ
※JavaScriptでは、グローバルスコープを利用することで、どこからでもアクセスできる変数や関数を定義することができるが、複数のスクリプトで同じ名前を使った場合、名前空間の衝突が発生する可能性がある。
=> モジュール化することで、モジュールごとに独自のスコープが作られるため、名前空間の衝突を回避することができる。

■ Export

  • モジュールから外部に公開する関数や変数を指定。
  • 先頭にExportを付けることにより、外部からアクセス可能な関数になる。
複数の書き方がある

ex. 1. 変数の先頭につける方法

export const hello = () => {
   console.log("hello!")
};

このようにすると、helloという関数が外部でも使用できるようになる。
ex. 2. objectリテラルとしてあげる

class = User{
 constoructor(name){
    this.name = name;
  }
}

export {User}

上で定義したUserクラスが外部から使用できるようになる。

※arrow関数のルールで、arrow関数には**thisが存在せず、その代わりに外側のスコープのthisを参> 照**する。とあったと思うがこういうことだ!

■ import

  • 他のモジュールから関数や変数を読み込むための構文.
  • ex. module.jsで exportしたhelloという関数をmain.jsで使用する
import {hello} from "./module.js";

hello();
//hello
  • importは複数読み込むとき、基本的に上にまとめて記述すること。
  • 同じファイルから複数importする場合は同じ行でまとめて記述可能。
import {hello,〇〇} from "./module.js";

DOMについて入門知識

DOMとは?
HTMLなどの文章を扱うための手法の1つ。
HTMLをJavaScriptから参照、更新するためのインターフェイス
(HTMLは文章であって、JavaScriptでHTMLを扱うときにはオブジェクトに変換しないといけない。)

DOMでは対象となる各要素(bodyタグなど)を抽出し、それを階層構造として扱う。

"文章を扱うための手法"...どういうこと??

DOMとは、"文章を扱うための手法" とかいたがどういうことか。
(文章?...文章? 私は最初納得できなかった。笑)

"HTMLをJavaScriptから参照、更新する"という言い方も書いたが、
そもそもHTML(hypertext markup language)は...
= ウェブサイトのコンテンツの構造を作るために使うマークアップ言語。
= "HTML文章"とも呼ばれる。
=> 文章 = 英語ではDocument

HTML上では、タグ(文章)の形で構成が表現されているが、
JavaScriptでは、DOMというオブジェクトの形でHTMLを表現する。

だから、
"HTML文章を、(JavaScript上で)扱う、変換する"必要があり、
その変換されたものがDOM(Document Object Model というオブジェクト)なわけだ!

(私はこれで納得いったがどうだろう。もう少し整理できそう。誰かあれば教えてください。)

DOM ツリー
上記で、階層構造として扱うと記述したが、この階層構造のことをDOMツリーという。

どのようになっているか
HTML構文を参考にしてDOMツリーを作成します。

そうしてこのDOMツリーがJAVASCRIPTエンジン上に保持されるようになる。

■ このDOMツリーを構成する要素を"ノード(Node)"という。
よって、DOMツリーはノードの集合で構成されているとも言える。

前提知識

ここではJavaScriptでコードを書くにあたっての前提知識について記述します。
触っている人は飛ばしてください~~

■ 変数(variable)と、その種類について

変数とは、"名前付けされた格納場所" であり、
繰り返し使う値を格納しておくもの。

<変数の種類について>

変数 再代入 関数スコープを生成 ブロックスコープを生成
let (ES6~) 可能
const (ES6~) 不可能
var (非推奨) 可能 ×

ひとまず、varについては、現在のJavaScriptでは非推奨となっているため、
使わないようにしよう。

変数のscopeについては以下のタブに格納しているため、興味がある方は見てください。

補足:変数のスコープについて

ひとまず、scopeとは

スコープ(scope)とは:
変数がどの場所から参照できるのかを定義する概念のこと.
変数の有効範囲.

<scopeの種類>

  • グローバルスコープ: プログラム全体のどこからでもアクセス可能
  • ローカルスコープ: グローバル変数以外の全ての変数はローカルスコープを持つローカル変数。
    • 関数スコープ
    • ブロックスコープ
      グローバルスコープとローカルスコープの二種類があり、
      さらにローカルスコープは関数スコープブロックスコープに分類される。

<関数スコープ>
関数内で宣言された変数は、その関数内部でのみアクセス可能!

function localScopeExample() {
    var localVar = "I am local";
    console.log(localVar); // "I am local"
}

localScopeExample();
console.log(localVar); // エラー: localVar is not defined

<ブロックスコープ>
ES6(ECMAScript 2015)からは、letconstを使用して変数を宣言することで、
ブロックスコープを作成できるようになった。
ブロックスコープは、中括弧 {} で囲まれた領域内で変数が有効

if (true) {
    var functionScopedVar = "I am function-scoped with var";
    let blockScopedVar = "I am block-scoped with let";
}

console.log(functionScopedVar); // "I am function-scoped with var"
console.log(blockScopedVar); // エラー: blockScopedVar is not defined

■ 関数(function)について

一連の手続き(処理)を実行する文の集まり。

function fn(仮引数){
return 戻り値;
}

// 関数の呼び出しは、以下のように記述。
fn(実引数);
  • 関数に渡す変数が引数

    細かくしたら、呼び出し元に渡す引数のことを実引数
    宣言の時に設定している引数を仮引数と呼ぶ。

  • 関数を実行した結果を呼び出し元に返す値を戻り値

■ オブジェクト:object

名前(プロパティー、またはキー)と、値(バリュー)を
ペアで管理する入れ物。
"異なるデータ型の値をまとめて管理するためのコンテナ"ともいう。
ex.

const person = {
    firstName: "John",
    lastName: "Doe",
    age: 30,
    isStudent: false
};

上記の例では、person オブジェクトが作成されており、
それぞれのプロパティに名前と値のペアが含まれている。
firstNameプロパティの値は,"John" です。のように。

値(バリュー)について、文字列や数字はもちろんだが、以下のように、
関数やその他のオブジェクトも格納が可能。

let obj={
  property1='Hello', // 文字列
  property2=function(){
  },   // 関数(オブジェクト設定の際は、無名関数で書くのが一般的)
  property3={
    message:"Bye"
  }
}

補足:オブジェクトの中での関数について
オブジェクトの中で定義する際は、無名関数で定義することが一般的。
また、オブジェクトのプロパティに格納された関数のことはメソッドと表現する。

オブジェクトの操作方法
オブジェクトのプロパティには、
ドット演算子 . やブラケット記法 [] を使用してアクセスできる。

console.log(person.firstName); // "John"
console.log(person["age"]); // 30
補足:ドットとブラケット記法について

ドット記法とブラケット記法の違いは、プロパティ名が引用符で囲われているか、も大きな違いだ。
囲われている = プロパティ名が “文字列” として指定されている、ということ。

■ ドット記法 (Dot Notation)

ドット記法は、オブジェクトのプロパティやメソッドにアクセスするための一般的な方法。
<ドット記法の特徴>

  • プロパティ名またはメソッド名をオブジェクト名の後にドット (.) で繋げて指定。
  • ドットの後には、プロパティ名やメソッド名を識別子として記述。
    ex. object.propertyobject.method()
const person = {
  firstName: "John",
  lastName: "Doe",
  getFullName: function() {
    return this.firstName + " " + this.lastName;
  }
};
console.log(person.firstName); // John
console.log(person.getFullName()); // John Doe

■ ブラケット記法(Bracket Notation)

ブラケット記法は、オブジェクトのプロパティやメソッドにアクセスするための代替的な方法。
<ブラケット記法の特徴>

  • プロパティ名やメソッド名を引用符(シングルクォートまたはダブルクォート)で囲み、
    オブジェクト名の後に角括弧 ([]) でくくって指定。
  • 引用符で囲まない場合、識別子として解釈され、変数としての値を参照できる。
    ブラケット記法の利点は、変数や計算結果を用いてプロパティ名やメソッド名を動的に指定できる点。
const person = {
  firstName: "John",
  lastName: "Doe",
  getFullName: function() {
    return this.firstName + " " + this.lastName;
  }
};
const propertyName = "firstName";
console.log(person[propertyName]); // John

const methodName = "getFullName";
console.log(person[methodName]()); // John Doe

また引き続き仕組みや必要な知識について、アウトプットしたいと思います。
補足点や、間違い等見つけましたら、コメントください!

ここまでみていただきありがとうございました!また!

Discussion