奥が深い関数、詳細は [関数と宣言 · JavaScript Primer \#jsprimer](https://jsprimer.net/basic/function-declaration/) を読んでもらうとして、Lessonでは重要なポイントのみを抑えていきます。 ## Reference - [関数と宣言 · JavaScript Primer \#jsprimer](https://jsprimer.net/basic/function-declaration/) ## Lesson 関数宣言は `function` キーワードを使います。 ```js function funcName(arg1, arg2) { return arg1 + arg2; } ``` 変数に関数を代入する場合や、一時的に利用する無名関数としては、[[アロー関数 (JavaScript)|アロー関数]]を使うことが多いです。 ```js const funcName = (arg1, arg2) => arg1 + arg2; ``` ## Mission 1 #😁EASY 2つの値を引数にとり、大きい値を返す関数を書いてください。 - 引数のバリデーションは不要 (必ず数値型) - 呼び出し側から必ず2つの引数が渡される前提でOK - 同じ値の場合はどちらを返してもよい - `function` キーワードを使うこと %% 解答例 [[三項演算子 (JavaScript)|三項演算子]]を使うとシンプルに書けます。(まだやってないので使わなくてもOK) ```js function max(x, y) { return x > y ? x : y; } ``` %% ## Mission 2 #😁EASY Mission 1の関数を[[アロー関数 (JavaScript)|アロー関数]]で書き直してください。 %% 解答例 ```js const max = (x, y) => (x > y ? x : y); ``` %% ## Mission 3 #🙂NORMAL [[残余引数 (JavaScript)|残余引数]]を使って、可変長の引数を受け取り総和を返却する関数 `sum` を作成し、[[スプレッド構文 (JavaScript)|スプレッド構文]]を使って呼び出すコードを書いてください。 - 引数は必ず1つ以上指定されるという前提でOK - 引数のバリデーションは不要 (必ず数値型) ```js // TODO: sumの実装 const nums = [1, 10, 100] // TODO: numsを使ってsumを呼び出し、console.logで出力 ``` %% 解答例 実装は任意の方法でOKです。ループや配列に関するクエストはまだ実施していないため。 ```js // for文ですべてを加算する function sum(...args) { let total = 0; for (const arg of args) { total += arg; } return total; } const nums = [1, 10, 100] console.log(sum(...nums)) ``` または ```js // reduceで畳み込み const sum = (...args) => args.reduce((ac, x) => ac + x); const nums = [1, 10, 100] console.log(sum(...nums)) ``` %% > [!hint]- Hint 1 > [[残余引数 (JavaScript)|残余引数]]は[[配列 (JavaScript)|配列]]データになるので、[[for...of (JavaScript)|for...of]]を使って加算しましょう。 ## Mission 4 #😵HARD Mission 1の関数について、呼び出し側が必ず引数を2つ渡さない場合でも動く関数を書いてください。 - 引数が渡されたら必ず数値型という前提でOK - 関数名を `max` として以下を満たすこと ```js max() // 0 (引数なしは0を返す) max(1) // 1 (引数1つはそのまま返す) max(1, 2) // 2 max(1, 2, 3) // 2 (引数3つ目以上は無視でいい) ``` %% 解答例 [[残余引数 (JavaScript)|残余引数]]を使って可変長の引数を表現し、[[分割代入 (JavaScript)|分割代入]]で1つ目と2つ目の引数のみにフォーカスする。未指定の場合は [[undefined (JavaScript)|undefined]] になり、引数が指定された場合は必ず数値型という前提があるのでこれでOK。 ```js // 関数の仮引数に対する分割代入と残余引数を組み合わせる場合 function max(...[x, y]) { if (x === undefined) { return 0; } // if (!y) { だと max(-1, 0) が -1 になってしまうのでNG if (y === undefined) { return x; } return x > y ? x : y; } ``` または ```js // 残余引数を関数内で分割代入する場合 function max(...args) { const [x, y] = args; if (x === undefined) { return 0; } // if (!y) { だと max(-1, 0) が -1 になってしまうのでNG if (y === undefined) { return x; } return x > y ? x : y; } ``` または ```js function max(...args) { if (args.length === 0) { return 0; } else if (args.length === 1) { return args[0]; } else { return args[0] > args[1] ? args[0] : args[1]; } } ``` %% > [!hint]- Hint 1 > 可変長の引数は[[残余引数 (JavaScript)|残余引数]]で表現すると分かりやすいです。 > [!hint]- Hint 2 > 前提条件があるので、[[undefined (JavaScript)|undefined]]が引数として指定されるケースを考える必要はありません。(引数の数が足りない場合、そこは[[undefined (JavaScript)|undefined]]になりますが) --- *NEXT* >> [[📗TDQ-009 条件分岐と三項演算子]]