4歳娘「パパ、constしか使わないで？」

## 休日ワイ

ワイ「（カタカタカタカタカタ・・・）」
ワイ「（**ッターーーーン！！！**）」
ワイ「あっ、**ぜんぶ消えてもうた**」

娘（**4歳**）「パパ？」
娘「私のお願いしたシステム、作ってくれた？」
娘「**曜日によって色々なメッセージが表示される**システム」

ワイ「おお、鋭意製作中やで**（震え声**」
ワイ「今、**休日かどうかを表示する機能**のコーディングを開始したところや」

```js:JavaScript
// 曜日番号を取得。
const dayNumber = new Date().getDay();
```

ワイ「まず、↑ここで**曜日の番号**を取得して」
ワイ「`dayNumber`っていう名前を付けてんねん」
ワイ「ちなみに、番号と曜日の対応は・・・」

> 0 → 日曜日
1 → 月曜日
2 → 火曜日
3 → 水曜日
4 → 木曜日
5 → 金曜日
6 → 土曜日

ワイ「↑こんな感じやな」
ワイ「つまり、`0`と`6`が**土日**やから**お休み**やねん」

娘「うんうん」

ワイ「せやから・・・」

```js:JavaScript
const isHoliday = dayNumber === 0 || dayNumber === 6;
```

ワイ「`dayNumber`が、`0`または`6`の場合は」
ワイ「変数`isHoliday`が`true`になるようにしてんねん」

娘「なるほどね」
娘「逆に`0`か`6`以外の場合は`isHoliday`が`false`になるんだね」

ワイ「せや」
ワイ「それで、`isHoliday`が`true`なのか`false`なのかによって」
ワイ「表示する文字列を変えるんや」

```js:JavaScript
let dayText;

if (isHoliday) {
  dayText = "お休み";
} else {
  dayText = "平日";
}
```

ワイ「↑こうやな」

娘「**パパ、`let`を使わないで？**」

ワイ「え・・・・・？」

娘「**`const`しか使わないで？**」

ワイ「なんで・・・・・？」

娘「`const`なら**再代入されない**から多少の安心感があるけど」
娘「`let`だと、どこかで**変な値が再代入**されそうで」
娘「**とっても不安なの・・・**」

ワイ「ええ・・・・・？」

娘「コードを読むときも、**変数の中身が変わる可能性**を意識して読まないといけないから」
娘「疲れちゃうし・・・」

ワイ「ああ・・・」

娘「もっと言うと、`const`でも不安なくらいなの」
娘「`const`で宣言した変数でも、オブジェクトのプロパティは上書きできちゃうからね」
娘「だから、`let`なんてもう**耐えられないの**」

ワイ「そうなんか・・・・・」

## 条件分岐したい時はどうする

ワイ「でもな、娘ちゃん・・・」

```js:JavaScript
let dayText;

if (isHoliday) {
  dayText = "お休み";
} else {
  dayText = "平日";
}
```

ワイ「↑こんな感じで、**if文で**条件分岐して」
ワイ「それによって代入する値を変えたい時はどうすんの・・・？」

```js:JavaScript
const dayText = if (isHoliday) {
  "お休み";
} else {
  "平日";
}
```

ワイ「↑こんな感じか？」

娘「いや、それだと**エラー**が出ちゃうね」
娘「`if`文は、**文**だから**値を返せないの**」

ワイ「ほえぇ・・・」

娘「だから、そういう場合は・・・」

```js:JavaScript
const dayText = isHoliday ? "お休み" : "平日";
```

娘「↑これでいいんじゃない？」

ワイ「いや、**三項演算子**は・・・」
ワイ「**宗教上の理由**で使えへんねん」

娘「そっか」
娘「じゃあ・・・」

```js:JavaScript
const dayText = (() => {
  if (isHoliday) {
    return "お休み";
  } else {
    return "平日";
  }
})();
```

娘「↑これはどう？」

ワイ「何これ」

娘「関数をその場で作って実行して、`"お休み"`または`"平日"`と言う文字列を返してるの」
娘「`isHoliday`が`true`なのか`false`なのかによって」
娘「返す文字列が変わる・・・」
娘「そんな関数だね」

ワイ「**関数をその場で作って実行**・・・？」
ワイ「ぐぬぬ・・・」
ワイ「こんなんを頻繁に書く自信ないわ・・・」

娘「仕方ないなぁ」
娘「じゃあ」
娘「**値を返せる`if`**みたいな**関数**を作ってあげるね」

## 関数`iff`

娘「はい、どうぞ！」

```js:JavaScript
const iff = condition => {
  const thenMethod = thenFunc => {
    const elseMethod = elseFunc => {
      return condition ? thenFunc() : elseFunc();
    }
    return { else: elseMethod };
  };
  return { then: thenMethod };
};
```

娘「`if`は予約語だから`iff`って名前にしたよ」

ワイ「何これ」
ワイ「ぜんぜん読めへんけど」

娘「うーん」
娘「とりあえずね・・・」

```js:JavaScript
const dayText =
  iff(isHoliday)
    .then(() => "お休み")
    .else(() => "平日");
```

娘「使い方は↑こんな感じ」

ワイ「おお、使い方は割とシンプルやな」
ワイ「なんか、**Elm**の`if`式に似てるな」


```elm:Elm
dayText =
    if isHoliday then
        "お休み"

    else
        "平日"
```

ワイ「Elmだと↑こうやもんな」
ワイ「そうか、Elmの`if`は**式**だから**値を返せる**んやな」

娘「うん」
娘「おんなじ感じだね」
娘「っていうか真似したんだけどね」

ワイ「でも娘ちゃん」
ワイ「**なんか処理**した結果を返したい場合はどうするん？」
ワイ「例えば`if`文で言うと・・・」

```js:JavaScript
let dayText;

if (isHoliday) {
  const a = "お";
  const b = "休";
  const c = "み";

  const holidayText = a + b + c;

  dayText = holidayText;
} else {
  const a = "平";
  const b = "日";

  const weekdayText = a + b;

  dayText = weekdayText;
}
```

ワイ「↑こんな感じで」
ワイ「文字列を結合してから使いたい場合とか」

娘「そういう場合は・・・」

```js:JavaScript
const dayText =
  iff(isHoliday)
    .then(() => {
      const a = "お";
      const b = "休";
      const c = "み";

      const holidayText = a + b + c;

      return holidayText;
    })
    .else(() => {
      const a = "平";
      const b = "日";

      const weekdayText = a + b;

      return weekdayText;
    });
```

娘「↑こんな感じだね」

ワイ「そうか」
ワイ「`then`メソッドや`else`メソッドに渡す関数の中で」
ワイ「`return`で値を返せばええんやな」

娘「そうそう」

## これで`let`なしで行けそうだが・・・？

ワイ「ありがとうやで娘ちゃん」
ワイ「これで`let`なしで行けそうや」
ワイ「次は**曜日に合わせたメッセージを表示する機能**や」
ワイ「（カタカタカタカタ・・・）」
ワイ「**・・・あれ！？**」

```js:JavaScript
let dayMessage;

switch (dayNumber) {
  case 0:
    dayMessage = "日曜日やで！ゆっくり休んでや！";
    break;
  case 1:
    dayMessage = "月曜日やで！今週も頑張ろうな！";
    break;
  case 2:
    dayMessage = "火曜日やで！";
    break;
  case 3:
    dayMessage = "水曜日やで！";
    break;
  case 4:
    dayMessage = "木曜日やで！";
    break;
  case 5:
    dayMessage = "金曜日やで！もう少しで休みや！";
    break;
  case 6:
    dayMessage = "土曜日やで！明日も休みやで！";
    break;
  default:
    dayMessage = "曜日番号がおかしいで！";
    break;
}
```

ワイ「↑この部分どうしよ・・・」
ワイ「`let`使ってもうたわ・・・」
ワイ「`switch`文のときは使いたくなるなぁ・・・」

娘「仕方ないなぁ」
娘「じゃあ」
娘「`switch`っぽくて**値を返せる**関数も作るね」

## 関数`switchf`

娘「はい、できたよ！」

```js:JavaScript
const switchf = switchVal => {
  const caseMethod = (funcToDo) => caseVal => {
    const isFixedNow = !funcToDo && switchVal === caseVal;
    const thenMethod = (funcToDo, isFixedNow) => thenFunc => {
      const defaultMethod = (funcToDo) => defaultFunc => {
        return (funcToDo || defaultFunc)();
      };
      return {
        case: caseMethod(isFixedNow ? thenFunc : funcToDo),
        default: defaultMethod(isFixedNow ? thenFunc : funcToDo)
      };
    };
    return { then: thenMethod(funcToDo, isFixedNow) };
  };
  return { case: caseMethod() };
};
```

娘「`switch`も予約語だから`switchf`って名前にしたよ」

ワイ「これまた訳わからんコードやな」

娘「使い方は↓こんな感じ」

```js:JavaScript
const dayMessage =
  switchf(dayNumber)
    .case(0).then(() => "日曜日やで！ゆっくり休んでや！")
    .case(1).then(() => "月曜日やで！今週も頑張ろうな！")
    .case(2).then(() => "火曜日やで！")
    .case(3).then(() => "水曜日やで！")
    .case(4).then(() => "木曜日やで！")
    .case(5).then(() => "金曜日やで！もう少しで休みや！")
    .case(6).then(() => "土曜日やで！明日も休みやで！")
    .default(() => "曜日番号がおかしいで！");
```

ワイ「ほええ、今回も使い方は簡単なんやな」

娘「うん」

ワイ「でもさ、それくらいなら**ただのオブジェクト**か**配列**でも良くない？」

```js:JavaScript
const dayMessageMap = {
  0: "日曜日やで！ゆっくり休んでや！",
  1: "月曜日やで！今週も頑張ろうな！",
  2: "火曜日やで！",
  3: "水曜日やで！",
  4: "木曜日やで！",
  5: "金曜日やで！もう少しで休みや！",
  6: "土曜日やで！明日も休みやで！"
};

// または
const dayMessages = [
  "日曜日やで！ゆっくり休んでや！",
  "月曜日やで！今週も頑張ろうな！",
  "火曜日やで！",
  "水曜日やで！",
  "木曜日やで！",
  "金曜日やで！もう少しで休みや！",
  "土曜日やで！明日も休みやで！"
];
```

ワイ「↑これでも、曜日番号を元にメッセージを取得できるで」

娘「まあね」
娘「でも`switchf`関数なら`default`メソッドもあるよ」

ワイ「ああ、なるほど」
ワイ「**どのケースとも一致しなかった場合**のことも指定できるわけか」
ワイ「それはええかもね」
ワイ「ありがとうやで、娘ちゃん！」

## これで何とかなりそう

ワイ「これで何とか`const`だけで行けそうや・・・」
ワイ「それにしても」
ワイ「娘ちゃんの**『再代入できる隙を作らない』**という強いこだわり・・・」
ワイ「感動したわ・・・！」

娘「てへへ」

ワイ「関数も、2つも作ってくれてありがとうな」
ワイ「お礼にこの**お菓子とジュース**をあげるから、**向こうの部屋で**飲んできいや？」

娘「わーい、ありがとうパパ！」

ワイ「**ゆっくり**飲んで来てな！」

娘「うん！」

ワイ「・・・よし、行ったな」
ワイ「これで**再代入し放題や！！！**」
ワイ「**手続き**大好きや！！！」
ワイ「**副作用**？そんなん知らんわ！！！」

よめ太郎「（**クズやん**）」

**〜おしまい〜**

## この記事もよろしくやで！

[**4歳娘「パパ、懐かしいJavaScript書いてるね！」**](https://qiita.com/Yametaro/items/70e7878c5ea51788b643)