JavaScript　覚えておくべき注意点！（７）　ジャンケンゲームを関数を使って書き直す / 無名関数

###★ 関数にする部分を考える
関数の主なメリットは「プログラムが読みやすくなる」「プログラムが再利用しやすくなる」の2つでした。
今回は「再利用」の予定がないので「プログラムが読みやすくなる」メリットを重点的に考えていきます。

▲ジャンケンゲームを構成する機能

-  人間に手を入力してもらう機能........................................................getHumHand関数
- 入力氏がおかしかったときにメッセージを出す機能........................そのまま利用
- コンピュータの手を決める機能........................................................getComHand関数
- 最終的な結果を表示する機能...........................getResult関数、getResultMsg関数

###★ 人間に手を入力してもらう
１．ジャンケンの手の番号を設定する

```javascript:janken1.js

/* 変数定義 ************************/
// ジャンケンの手の番号を設定
var GU    = 1;
var CHOKI = 2;
var PA    = 3;
```
２．ジャンケンの手の入力を関数化する
ジャンケンの手の入力処理を処理していた部分を関数化します。
関数の機能は「人間のジャンケンの手を取得すること」なので、英語の「get Human Hand」を略して「getHumHand」としてみます。
ジャンケンの手に該当するときは入力された値をそのまま返し、それ以外のときはundefinedを返します。

```javascript:janken2.js

/* 関数定義 ************************/
// 人間に手を入力してもらう機能
function getHumHand() {
    var hum = prompt('半角数字で1~3の数字を入力してください。\n\n' + GU + ':グー\n' + CHOKI + ':チョキ\n' + PA + ':パー');
  hum = parseInt(hum, 10);
  if (hum !== GU && hum !== CHOKI && hum !== PA) {
    return undefined;
  } else {
    return hum;
  }
}
```
３．作った関数を呼び出す

```javascript:jyanken3.js
 
/* 実行する処理 ************************/
var hum = getHumHand();
console.log(hum); この行は動作確認したらすぐ消す
  }
}
```
### ★入力値がおかしいときにメッセージを表示する
１．入力値に応じて条件分岐する
「入力値がおかしかったときにメッセージを表示する機能」は、元々簡単なので、ここでは関数化しません。

point→
条件式で偽になる値

- 数値の0
- 数値のNaN
- 空白文字列の"(シングルクォート２つ)
- undefined
- null
- false

```javascript:janken4.js
 /* 実行する処理 ************************/
  var hum = getHumHand();
  if (!hum) {
    alert('入力値をうまく認識できませんでした。ブラウザを再読み込みすると、もう一度挑戦できます。');
  } else {
}
```
###★ コンピュータの手を決める 
１．コンピュータの手の決定を関数化する
関数名は英語の「get Computer Hand」を略して「getComHand」にしてみました。
Point→　関数化前のプログラムでは乱数を求めている事しかわかりません。関数化してgetComHandという名前を付けると、目的が分かりやすくなります。

```javascript:janken5.js

// コンピュータの手を決める
function getComHand() {
  return Math.floor(Math.random() * 3) + 1;
} // 以上は今回の書き込みの部分

/* 実行する処理 ************************/
var hum = getHumHand();
if (!hum) {
  alert('入力値をうまく認識できませんでした。ブラウザを再読み込みすると、もう一度挑戦できます。');
} else { // 関数を呼び出す　以下は今回の書き込み部分
  var com = getComHand(); 
  console.log(com); // この行は動作を確認したらすぐ消す
}
```

### ★ 最終的な結果を表示する
１．手の名前の取得を関数化する
「最終的な結果を表示する機能」は複雑なので、「コンピュータの手の名前を取得する機能」「ジャンケンの勝敗結果を判定する機能」「最終的な結果のメッセージを作る機能」の３つに分けて、それぞれ関数化していきます。

```javascript:jyanken6.js
 // コンピュータの手の名前を取得
  function getHandName(num) {
    switch (num) {
      case GU:
      return 'グー';
      case CHOKI:
      return 'チョキ';
      case PA:
      return 'パー';
    }
  }
```
Point→　getHandName関数は、「ジャンケンの手を表わす1～3の数値を受け取って、それに対応する「グー」「チョキ」「パー」のいずれかの文字列を返します。なので、関数の定義で引数numを用意してそこに数値を渡してもらい、return文で文字列を返しております。


２．ジャンケンの勝敗結果を判定する機能を関数化する
「Get Result」をそのまま「getResult」にしてみました。

```javascript:jyanken7.js
  // 結果の判定
  function getResult(com, hum) {
    if (hum === com) {
      return '結果はあいこでした。';
    } else if ((com === GU && hum === PA) || (com === CHOKI && hum === GU) || (com === PA && hum === CHOKI)) {
      return '勝ちました。';
    } else {
      return '負けました。';
    }
  }
```

３．最終的な結果のメッセージを作る機能を関数化する
「Get Result Message」として、それを連想できる「getResultMsg」を関数化してみました。

```javascript:jyanken8.js  
  // 最終的な結果のメッセージ
  function getResultMsg(com, hum) {
    return getResult(com, hum) + 'コンピュータの出した手は「' + getHandName(com) + '」でした';
  }

```

４．最終的な結果のメッセージを作る機能を関数化する

取得したメッセージをalertで表示します。

```javascript:jyanken9.js
  
  /* 実行する処理 ************************/
  var hum = getHumHand();
  if (!hum) {
    alert('入力値をうまく認識できませんでした。ブラウザを再読み込みすると、もう一度挑戦できます。');
  } else {
    var com = getComHand(); // 関数を呼び出して結果を表示
    alert(getResultMsg(com, hum));
  }
}
```

５．全体を１つの関数「janken」にする

```javascript:jyanken10.js

function janken () {
  /* 変数定義 ************************/
  // ジャンケンの手の番号を設定

```
```javascript:jyanken11.js
    alert(getResultMsg(com, hum));
  }
}

janken();
```

#### まとめ

```javascript:jyanken12.js

function janken () {
  /* 変数定義 ************************/
  // ジャンケンの手の番号を設定
  var GU    = 1;
  var CHOKI = 2;
  var PA    = 3;
  
  /* 関数定義 ************************/
  // 人間に手を入力してもらう機能
  function getHumHand() {
    var hum = prompt('半角数字で1~3の数字を入力してください。\n\n' + GU + ':グー\n' + CHOKI + ':チョキ\n' + PA + ':パー');
    hum = parseInt(hum, 10);
    if (hum !== GU && hum !== CHOKI && hum !== PA) {
      return undefined;
    } else {
      return hum;
    }
  }
  
  // コンピュータの手を決める
  function getComHand() {
    return Math.floor(Math.random() * 3) + 1;
  }
  
  // コンピュータの手の名前を取得
  function getHandName(num) {
    switch (num) {
      case GU:
      return 'グー';
      case CHOKI:
      return 'チョキ';
      case PA:
      return 'パー';
    }
  }
  
  // 結果の判定
  function getResult(com, hum) {
    if (hum === com) {
      return '結果はあいこでした。';
    } else if ((com === GU && hum === PA) || (com === CHOKI && hum === GU) || (com === PA && hum === CHOKI)) {
      return '勝ちました。';
    } else {
      return '負けました。';
    }
  }
  
  // 最終的な結果のメッセージ
  function getResultMsg(com, hum) {
    return getResult(com, hum) + 'コンピュータの出した手は「' + getHandName(com) + '」でした';
  }
  
  /* 実行する処理 ************************/
  var hum = getHumHand();
  if (!hum) {
    alert('入力値をうまく認識できませんでした。ブラウザを再読み込みすると、もう一度挑戦できます。');
  } else {
    var com = getComHand();
    alert(getResultMsg(com, hum));
  }
}

janken();
```

####無名関数
varを定義するときにfunctionの後の関数名を省略することができます。
この書き方を「無名関数」と言います。
単に関数を省略しただけだと呼び出すことができず「何も起きない」ので、一般的には定義と同時に変数に記憶したり、他の関数の引数として利用します。変数に記憶した場合は、名前のある関数と同じように「変数名()」という形式で呼び出すことができます。

```javascript:jyanken13.js

var 変数名 = function (引数１,引数２,...) {
	行いたい処理
	return 戻り値;
};
```

参照：[いちばんやさしいJavaScript](https://book.impress.co.jp/books/1116101117)