先輩から教えてもらったJavaScriptの知見を体験してみる

# 目的

- 先輩から教わったJavaScript（以降、js）の内容を忘れないように追体験しながら記事にまとめてみる

# 情報

- 下記の記事をもとにJavaScriptの基本を先輩から教わった。
    - [【ド基礎から始めるJS講座①】Objectが解ればJSの半分くらいは解った気になれる！](https://qiita.com/layzy_glp/items/8eef954eac74bf974d4a)
- 先輩の説明は非常にわかりやすく、理解が深まったが実際に手を動かさないと忘れそうなので自分なりのコードで内容をちょっと変えながら追体験しようと思う。

# 準備

- 下記コマンドを実行してデスクトップ上に「index_1.html」を作成する。

    ```terminal
    $ touch ~/Desktop/index_1.html
    ```

- 下記コマンドを実行して先に作成したファイルを開く。

    ```terminal
    $ vi ~/Desktop/index_1.html
    ```

- 下記の内容を追記する。

    ```~/Desktop/index_1.html
    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>JavaScript体験</title>
    </head>
    <body>
        <header></header>
        <main>
    
        </main>
        <footer></footer>
        <script type="text/javascript">
    
        </script>
    </body>
    </html>
    ```

# オブジェクトを定義して値を表示してみよう

- index_1.htmlを下記のように修正した。

    ```~/Desktop/index_1.html
    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>JavaScript体験</title>
    </head>
    <body>
        <header></header>
        <main>
            <p id="str_1"></p>
        </main>
        <footer></footer>
        <script type="text/javascript">
            const taki = {
                name: {
                    familyName: 'tachibana',
                    firstName: 'taki'
                },
                sex: 'man',
                age: 17
            }
            
            window.onload = function() {
                document.getElementById('str_1').innerText = taki.name.familyName + taki.name.firstName;
            }
        </script>
    </body>
    </html>
    ```

- 当該ページをブラウザで開いたところ下記のように表示された。（URL部分がindex_1.htmlをダブルクリックして表示したときと異なるがこれはVScodeのプラグインであるLive Serverによるものなので気にしなくて良い。）

    ![JavaScript体験_と_Zoomミーティング-6_png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e9136248-b54f-a5c9-c3a7-daa1f3fa432a.png)

- js部分だけを抜粋して何をやっているのか処理を追ってみる。

    ```~/Desktop/index_1.html
    <script type="text/javascript">
        /* takiという変数にオブジェクトを格納 */
        const taki = {
            name: {
                familyName: 'tachibana',
                firstName: 'taki'
            },
            sex: 'man',
            age: 17
        }
        
        /* ウインドウが読み込まれたらこの無名関数（クロージャ）内部の処理を実行する命令 */
        window.onload = function() {
            /* html要素のid値と表示する文字列を紐付ける処理 */
            document.getElementById('str_1').innerText = taki.name.familyName + taki.name.firstName;
        }
    </script>
    ```

# フルネームを出力している部分を関数化してみる

- 下記のように修正してフルネームが出力されている処理を関数化してみた。

    ```~/Desktop/index_1.html
    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>JavaScript体験</title>
    </head>
    <body>
        <header></header>
        <main>
            <p id="str_1"></p>
        </main>
        <footer></footer>
        <script type="text/javascript">
            /* takiという変数にオブジェクトを格納 */
            const taki = {
                name: {
                    familyName: 'tachibana',
                    firstName: 'taki'
                },
                sex: 'man',
                age: 17,
            }
            
            function getFullnameOfTaki() {
                return taki.name.familyName + taki.name.firstName;
            }
            /* ウインドウが読み込まれたらこの無名関数（クロージャ）内部の処理を実行する命令 */
            window.onload = function() {
                /* html要素のid値と表示する文字列を紐付ける処理 */
                document.getElementById('str_1').innerText = getFullnameOfTaki();
            }
        </script>
    </body>
    </html>
    ```

- 内部処理をただ関数化しただけなので画面の表示は変わらない

# 関数化した処理をオブジェクトの中に格納してメソッド化する

- 下記のように修正してフルネームの関数をオブジェクトの中に記載してみた。

    ```~/Desktop/index_1.html
    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>JavaScript体験</title>
    </head>
    <body>
        <header></header>
        <main>
            <p id="str_1"></p>
        </main>
        <footer></footer>
        <script type="text/javascript">
            /* takiという変数にオブジェクトを格納 */
            const taki = {
                name: {
                    familyName: 'tachibana',
                    firstName: 'taki',
                },
                sex: 'man',
                age: 17,
                getFullname: function(){
                    return taki.name.familyName + taki.name.firstName;
                }
            }

            /* ウインドウが読み込まれたらこの無名関数（クロージャ）内部の処理を実行する命令 */
            window.onload = function() {
                /* html要素のid値と表示する文字列を紐付ける処理 */
                document.getElementById('str_1').innerText = taki.getFullname();
            }
        </script>
    </body>
    </html>
    ```

- 関数化したものをオブジェクトのメソッドとして記載しそのメソッドを呼んでいるだけなので表示は変わらない。

# メソッド定義部分を省略して記載してみる

- 下記のように記載してメソッドのクロージャ部分を省略記載にしてみた。

    ```~/Desktop/index_1.html
    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>JavaScript体験</title>
    </head>
    <body>
        <header></header>
        <main>
            <p id="str_1"></p>
        </main>
        <footer></footer>
        <script type="text/javascript">
            /* takiという変数にオブジェクトを格納 */
            const taki = {
                name: {
                    familyName: 'tachibana',
                    firstName: 'taki',
                },
                sex: 'man',
                age: 17,
                getFullname: () => taki.name.familyName + taki.name.firstName
            }

            /* ウインドウが読み込まれたらこの無名関数（クロージャ）内部の処理を実行する命令 */
            window.onload = function() {
                /* html要素のid値と表示する文字列を紐付ける処理 */
                document.getElementById('str_1').innerText = taki.getFullname();
            }
        </script>
    </body>
    </html>
    ```

- クロージャ部分をダブルアローで省略することで非常にスマートになり記載量も減った。瞬時の可読性は下がるかもだがソースが短いほうが読む人の心の負担が減る気がするので積極的に使いたい。jsでクロージャを使うとスレッドを分けるらしくどんどん使用してゆこうと思った。

# クラスを使ってみる

- 下記のように修正してまとめられそうな処理をクラス化した。

    ```~/Desktop/index_1.html
    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>JavaScript体験</title>
    </head>
    <body>
        <header></header>
        <main>
            <p id="str_1"></p>
        </main>
        <footer></footer>
        <script type="text/javascript">
            class info {
                constructor(familyName, firstName, sex, age) {
                    this.name = {
                        familyName: familyName,
                        firstName: firstName,
                    };
                    this.sex = sex;
                    this.age = age;
                    this.getFullname = () => this.name.familyName + this.name.firstName;
                }
            };

            /* ウインドウが読み込まれたらこの無名関数（クロージャ）内部の処理を実行する命令 */
            window.onload = function() {
                /* html要素のid値と表示する文字列を紐付ける処理 */
                document.getElementById('str_1').innerText = new info('tatibana', 'taki', 'man', 17).getFullname();
            };
        </script>
    </body>
    </html>
    ```

- 処理をクラスにまとめただけなので表示は変化しない。
- せっかく処理をクラスにまとめたので他の情報も表示してみる。下記のように修正した。

    ```~/Desktop/index_1.html
    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>JavaScript体験</title>
    </head>
    <body>
        <header></header>
        <main>
            <p id="str_1"></p>
            <p id="str_2"></p>
        </main>
        <footer></footer>
        <script type="text/javascript">
            class info {
                constructor(familyName, firstName, sex, age) {
                    this.name = {
                        familyName: familyName,
                        firstName: firstName,
                    };
                    this.sex = sex;
                    this.age = age;
                    this.getFullname = () => this.name.familyName + this.name.firstName;
                }
            };

            /* ウインドウが読み込まれたらこの無名関数（クロージャ）内部の処理を実行する命令 */
            window.onload = function() {
                /* html要素のid値と表示する文字列を紐付ける処理 */
                document.getElementById('str_1').innerText = new info('tatibana', 'taki', 'man', 17).getFullname();
                document.getElementById('str_2').innerText = new info('miyamizu', 'mituha', 'woman', 20).getFullname();
            };
        </script>
    </body>
    </html>
    ```

- 下記のように表示される。

    ![JavaScript体験.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/04d90c82-cf7a-70b9-a406-4649972b7d82.png)