フルスタックプログラマーの卵どもにおくる、独学チートシート : 2

## 卵どもに贈る独学チートシートの続き
[前回記事](https://qiita.com/monsoonTropicalBird/items/572e1d02e63cff7a0462)を勢いよく書き出したのは良いものの、途中で書くことが多すぎて挫折、後半部分はサマリーのみで逃亡したわけですが、今いるマニラは長期連休で暇やなあと思っていた時に、あれを書き切ってしまわんといかんと思って戻ってきました。
正直Qiitaなどに駄文を書いたところで何の儲けにもならず、下手を打てば１００戦錬磨のプログラマー諸先輩方からの厳しいツッコミに晒されて蜂の巣にされるわけで、リスクしかないわけですが、前回かなりのいいねやストックをしていただいていた方々がおり、続きを書かねばならぬという気持ちになりました。卵のみんな、ありがとな。
では、続きのJavaScriptから。
## JavaScript

- JavaScriptの大部分はオブジェクトで出来ている
- APIの理解とJSONの処理
- Promise, async/awaitの理解
- ファンクションはいつ動くのか、同期、非同期処理の理解

前回書いたHTMLやCSSはマークアップ言語であって、プログラミング言語ではない。**なぜなら、データの処理はしていないからである**。書いたように、文章構造の定義と、装飾である。
で、色々なデータを料理する言語として、JavaScriptである。
ウェブ開発をしていると、おそらく、ここで躓く卵どもが多いと思う。わしも、２０年前にウェブをやっていたときは、正規表現やコールバックヘルなどに巻き込まれ、ここで挫折した。
JavaScriptが何やってるかというと、**何かをどうにかしてくれる**のである。
**何**と**どう**の部分を絶えず意識していれば、全く難しくない。
自分探しと同じで、**自分が何をどうしたいのか　が分かっている事が一番重要で**、JavaScriptは所詮、貴様のやりたい事をやってくれる道具であって、それ以上ではない。
で、**何**の部分には、
- 文字列
- 数字
- ブーリアン（true or false）
- undefined
- null （何も存在しない）

のどれかが入る。

![IMG_5982.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1204968/673e114d-2edc-4021-9129-248d0a316954.jpeg)


定義型だとかなんとか言われてるけど、結局はこれだけで、もっと整理されたデータやまとまったのデータを扱いたい場合は、ArrayかObjectに上記の値を突っ込んでおけばよい。
objectはシンプルに{key:value}というラベルと値のセットであり、arrayは値だけがズラッと入ってるイメージである。
**どうしたいか**の部分は、関数/Function と言われている部分で、まさにファンクション（機能）である。
基本の型は超シンプルで、
```javascript
keyword 名前 (材料) {
  材料 で 何かする
}

statement (この時) {
  これをする
}
```
これだけである。
具体的には、
```javascript
function printName(name) {
  console.log(`Hello ${name}`);
}

//もしくはアローファンクションなら
const printName = (name) =>{
  console.log(`Hello ${name}`);
}
```

```javascript
// if statement なら
const name = "Goku"

  if (name === "Goku") {
    console.log(`Ossu! ${name}`)
  } else {
    console.log(`Genkidesuka? ${name}`)
 }

// for statement なら
for (let i=0; i<=5; i++) {
   console.log('Ossu!');
}
 
```

で、functionとif statementなんかを組み合わせて、さらにクラスを定義して犬小屋を作るとしたら、

```javascript
// 犬小屋クラスを定義
class DogHouse {
  constructor(color, size) {
    this.color = color;
    this.size = size;
  }

  // 犬小屋を建てるメソッド
  build(budgetIsEnough) {
    return new Promise((resolve, reject) => {
      if(budgetIsEnough){
      resolve(`${this.color}色の${this.size}サイズの犬小屋がでけた！`);
      } else {
      reject("予算不足です");
      }
    });
  }
}

// 犬小屋を建てるファンクションを定義
const buildDogHouse = (color, size, budget) => {
  const myDogHouse = new DogHouse(color, size);
  return myDogHouse.build(budget);
}

// 犬小屋を建てるファンクションをトリガー
const dogHouse = buildDogHouse('金', '大きい', true)
console.log(dogHouse); // 金色の大きいサイズの犬小屋がでけた！

```

みたいなノリである。
color,size,budget などの、**何を** とbuild(),buidDgoHouse()の **どうする** で出来ている。クラスとオブジェクトに関しては、下記で説明しておく。
**JavaScriptを書くときは、常に何をどうしたいのか　を日本語で考えておく事。**
例えば、"user objectが入ったarray" を　"mapでループし" て `<div className="userList>` の中 に　"名前とID" 　を　"表示する" みたいな感じ。
**日本語（何であれ人間語）で書けるものは、ほとんどをコードに出来る。出来ないのは、あなたの言葉が破綻しているのだ。**
コードを書くコツとしては、まずコメントで、何をしたいか書き出し、具体的なコードはGoogle先生か、ChatGPT教授にでも聞けば助けてくれる。
**ChatGPTなどはコードの生成もしてくれるが、お前自身が何をしたいかよく分からなかったり、聞きたい事が正確でないと、返ってくるコードも間違ったコードしか返ってこない。**
例えば、下記は先ほど書いていたコードなんだけど、ユーザーがサインインして新しいuser documentがデーターベースに作られたら、そのdocument内のrefCodeの値をゲットして、それとマッチするドキュメントを探し、そのドキュメントのUIDをサインインしたユーザーのドキュメントに保存みたいな処理。
全体見ると、結構複雑なんだけど、１工程づつ書き出していけば、自分でやりたい事が理解しやすい。で、ここに実際のコードを埋めていけば良い。
ちなみにこれは、いわゆるネズミ講みたいに、サインインしたユーザーと、そのユーザーを紹介したユーザーを結び付ける処理。

``` javascript
// Step 1: When the new user document created, fetch document

// Step 2: get refCode in user document

// Step 3: Find the matched document by refCode

// Step 4: Find the uid from the matched document
   
// Step 5: Save the referer's UID to the created user's document
```

で、コードを埋めていくとこんな感じになる。長めのコードでも、１行づつ解決していくと、それほど難しくない。

``` javascript
// Step 1: When the new user document created, fetch document
 exports.updateReferenceOnUserCreation = functions.firestore.document("users/{userId}").onCreate(async (snap, context) => {
  const userDoc = snap.data();
  
    if (!userDoc) {
    console.log("No Documents Found");
    return null;
  }

// Step 2: get refCode in user document
  const userRefCode = userDoc.referenceCode.refCode;
  const userMyRefCode = userDoc.referenceCode.myRefCode;

    if (!userRefCode) {
    console.log("No reference code found for the user");
    return null;
  }

// Step 3: Find the matched document by refCode
  const querySnapshot = await db.collection("users").where("referenceCode.myRefCode", "==", userRefCode).get();

// Step 4: Find the UID from the matched document
  let matchedRefID;
  if (querySnapshot.empty) {
    matchedRefID = process.env.OWNER_UID;
  } else {
    const matchedDoc = querySnapshot.docs[0];
    matchedRefID = matchedDoc.data().uid;
  }
   
// Step 5: Save the referer's UID to the created user's document
  await snap.ref.update({
    "referenceCode.referer": matchedRefID,
  });
```


### JavaScriptの大部分はオブジェクトで出来ている
で、上でも書いたように、JavaScriptはデータを色々と処理してくれる。
例えば、ユーザーが書いたQiitaの記事のデータを、サーバーに送る、サーバーから返ってきたデータを、加工して表示するとか。そのほか色々お前ら次第。
で、そのデータっていうのは、上に書いた、テキスト、数字、ブーリアン値、null値の４種類であり、例えばフォームなら、名前、メール、住所、電話番号とか、一個一個処理してられないよね。なので、ObjectとかArrayにまとめてパッケージングしておけば扱いやすい。
**APIを介したデータの送受信、各種のライブラリ、JavaScriptそのものや、前回説明したHTMLのDOMに至るまで、ほぼ全てがオブジェクトという形でパッケージされていると言っても過言ではなく**、HTTPを使ったサーバーとフロントとのやり取りも、JSONというオブジェクトである。
JSONは、**サーバーとのやりとりは文字列データしか使えないため**、JavaScriptのオブジェクトを文字列変換したものに過ぎない。
なので、JavaScriptを理解しようと思えば、Objectを常に意識するのが、理解の近道だ。
オブジェクトについては、[以前記事](https://qiita.com/monsoonTropicalBird/items/8eba16bfd6aa64c08ced)に書いたので、これを読んで欲しい。

<iframe width="560" height="315" src="https://www.youtube.com/embed/T-HGdc8L-7w?si=pXCwtinz4OWsjgTV" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

### APIの理解とJSONの処理
[こちら](https://qiita.com/monsoonTropicalBird/items/4ec077170b8919287aa6)にもAPIについて書いたけど、ウェブ上のサービスの根幹がAPIで成り立っている。
すごく簡単なイメージとしては、ウーバーイーツである。
住所(URI)と注文(Request body)を送れば（HTTP Request）、レストランのキッチン（サーバー）が注文を作り、それをドライバーが受け取って送り返してくれる（HTTP Response） 。あとは、食うだけである。
やってることは、注文をだすのと、受け取りである。
料理はレストランのシェフが勝手に作ってくれるし、自分はレシピや材料を知る必要がない。
で、その注文と受け取った飯というのは、先に書いたJSON、つまりオブジェクトの形になって送受信される。
サーバーサイドのプログラムとは、このキッチンのオペレーションを作る事である。
例えば、ここのエンドポイントにアクセスすると、ダミーのブログ記事のデータがJSONで返ってくるのが見れる。
https://jsonplaceholder.typicode.com/posts
で、この返ってきたJSONデーターを、フロント側のHTMLに流し込めば、ブログページの出来上がりである。
`https://jsonplaceholder.typicode.com`　が住所、　`/posts`　が注文の部分である。

<iframe width="560" height="315" src="https://www.youtube.com/embed/tc8DU14qX6I?si=hlormWLGpvQamBqL" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
APIからデータを取得するような処理は、下に書く非同期処理に大きく関係してくる。
サーバーやデーターベースを介する処理は時間がかかるからである。つまり、下の例えでいうと、飯を炊くのと同じであり、データーをリクエストして待っている間に、他の処理を色々と出来た方が良いよねという事である。


### 同期、非同期処理とPromise

同期、非同期の理解は超重要で、超簡単である。
なぜなら、わしらは普段普通にやっているからだ。
元々のJavaScriptは、同期処理と言って、上のコードから順番にコード処理していっておった。
**で、これではあかんとなったわけだ。**
晩飯に豚汁、チャーハン、焼きサバを作る所をイメージしてみて欲しい。 
まず、飯を炊く。で、同期処理だと、飯が炊けるまで豚汁の具を準備することも、サバを焼くことも出来へん。
やっと飯が炊けたら、次は豚汁の具を切り、煮込むわけだが、具材に火が通るまで、鍋の前で待っていなければならず、チャーハンの準備も出来へん！自分の飯なら良いが、これが茶店のランチとかだったら大災害である。
グーグルマップとかに、「昼休みを返せ」とか、「一生行きません」とか「はよ潰れろ」などという心無いレビューが殺到することが目に見えている。こんなんじゃあかん。
で、Promiseと非同期処理である。
飯を炊飯器にセットしておくと、飯が炊けたら、炊けましたっていうブザーなりなんなりの合図が来るやん。それがまさにプロミスである。
で、その合図が来るまでに、例えば豚汁の具を刻む、鍋で煮る。鍋が煮立った頃に、これまた知らせてくれる。まさにプロミス。
プロミスは、その処理が成功か失敗か、途中なのかのステータスと、処理が成功した場合は、その成果物（ここでは炊けた飯、煮えた豚汁）を返してくれる。
もし、炊飯器が破壊されて飯が炊けんかった場合は、ちゃんと”炊飯器爆破”というエラーを返してくれる。
おかげで、他の作業をしていても、プロミスが成功し、炊けた飯が返ってきたタイミングで、チャーハンにとりかかれるというわけや！！つまり、非同期で、各作業が別々に同時的に行われている。
で、サバが焼ける頃には、豚汁はちょうど良い具合になっており、チャーハンも出来上がっているという”晩飯を作る”というタスクがコンプリートする。
上に書いたように、**Promiseっていうのは、上から下のフローから自由になり、作業が完了したら合図と成果物を返してくれるっていう、すごく便利な関数なわけだ。**
以下は典型的なPromiseを作るコード。１００歳以上を切り捨て、エラーを返す処理である。
```javascript
function promiseFunction(age) {
    return new Promise((resolve, reject) => {

        if (age < 100) {
            resolve("お前は、まだイケる");
        } else {
            reject("お前はもう、死んでいる");
        }
    });
}

promiseFunction(101)
    .then(result => console.log(result))
    .catch(error => console.error(error));

```
new Promise でプロミスオブジェクトを作り、return でそのオブジェクトを返している。
で、Promiseのコンストラクタは(resolve, reject)の２種類のコールバック関数を引数にとると決まってる。
resolve()は、成功した場合の値を返し、reject()は、エラーが発生した場合にこの値を返す。
簡単に言うと、処理が成功した場合はresolve()がトリガーされ、失敗したらreject()がトリガーされる。

### Async/Await
で、このプロミスの性質を利用したのが、ASYNC/AWAIT構文。
問えば、上記のチャーハンを作る関数を考えてみると、
```javascript 
const cookFriedRice = async() => {
    try {
        const rice = await cookRice();
        const friedRice = await fryRice(rice);
        console.log("Oishi!!!");
        return friedRice;
    } catch(err) {
         console.log(err.message);
        throw err;
    }
}
```

となる。
**Await をプロミスを返す関数の前に付ける**と、その作業が終わるまで次のコードを実行せずに待ってくれる。
つまり、ライスが出来たら、次のfryRice()に渡せるようにする。もし、これを普通の関数として実行すると、ご飯が炊ける前に、fryRice();関数が実行され、飯無しチャーハンが出来てしまう。
なぜなら、cookRice()もfryRice()も非同期関数で、上から下のフローとは無関係に動いているからである。非同期ファンクションをオーダー通りに実行させたい時に、async/await を使う。ちなみに、プロミスを返さない普通の同期ファンクション、例えばconsole.log にawait を付けても、何も起きない。
**で、このasyncを付けたcookFriedRice関数自体もプロミス関数と化す。**
つまり、チャーハンが出来た時点で、fullfiled か rejectを返してくる。また、friedRice をreturn しているので、調理できたらチャーハンが返ってくる。
晩飯の例で言うと、
```javascript
Promise.all([cookFriedRice(), cookSaba(), cookTonjiru()])
    .then(results => {
        console.log('Dinner completed successfully', results);
        eat(results);
    })
    .catch(error => {
        console.error('Dinner failed to resolve', error);
    });
```
とすると、全部の料理が出来たら、食べる　という処理が出来る。
普段ワシらが普通にやってるマルチタスクなんで、特に理解が難しいわけではないと思うんじゃ。

最後に、自分がJavaScriptの勉強でメチャ役に立った教材を。
<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?si=Iq5bqDA0ubt7Q3-u&amp;list=PL4cUxeGkcC9haFPT7J25Q9GRB_ZkFrQAc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?si=m_ZI9f9RUVF69-OG&amp;list=PL4cUxeGkcC9jx2TTZk3IGWKSbtugYdrlu" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

Net Ninja のチュートリアルにハズレなし。


<iframe width="560" height="315" src="https://www.youtube.com/embed/j59qQ7YWLxw?si=ovbYqD9bEQ-m8Cd9" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

この計算機アプリのチュートリアルは、JavaScriptの理解に個人的にメチャ役立った。


<iframe width="560" height="315" src="https://www.youtube.com/embed/R8rmfD9Y5-c?si=7w_q6tStKM7v6zm3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

Reactなんかのフレームワークを使う際、Array functionは必須。メチャよく使う。


あかん。。。。ここまで書いたらまたしんどくなってきた。JavaScriptしか書けんかった。。。サーバーとフレームワークはまた[次回](https://qiita.com/monsoonTropicalBird/items/af562370b390fb26dfdf)という事で許して。。。ゲフっッッッッっ