C
JavaScript/関数/Lesson 07

関数 — *再利用可能なコードブロック*

45分·theory
このチャプター
1/4

関数 — *再利用可能なコードブロック*

🎯 このレッスンを読んだら

このレッスンを最後まで読めば、以下の3つを自信を持って実践できます。

  • ✅ 関数宣言 vs. 関数式 + ホイスティングの違い
  • ✅ 引数のデフォルト値 + rest · spread の使い方
  • ✅ 純粋関数 / 副作用 / 第一級関数の定義

学習目標をチェックリストとして持ち、すべて答えられるようになったらレッスンを閉じましょう。

関数を書く4つの方法

関数の本質

関数 = 入力を受け取り、処理して結果を返す再利用可能なコードブロック。JS では関数は第一級市民 (first-class citizen) — 変数と同様に扱えます。

4つの書き方

javascript
// 1️⃣ 関数宣言 (function declaration)
function add1(a, b) {
    return a + b;
}

// 2️⃣ 関数式 (function expression)
const add2 = function(a, b) {
    return a + b;
};

// 3️⃣ アロー関数 (arrow function, 2015+) — 最も一般的
const add3 = (a, b) => a + b;

// 4️⃣ メソッド (オブジェクト内)
const calculator = {
    add(a, b) { return a + b; }
};

// ▶️ 4つすべて呼び出し — 結果は同じ
console.log(add1(2, 3));            // 5
console.log(add2(2, 3));            // 5
console.log(add3(2, 3));            // 5
console.log(calculator.add(2, 3));  // 5

// 💡 同じ名前(`add`)で4回宣言するとSyntaxError → 学習用にadd1·2·3と分離

関数宣言 vs. アロー関数 — どちらを使う?

関数宣言:

  • ホイスティング(宣言前に使用可能)
  • 独自の this を持つ
  • function キーワードを使用

アロー関数:

  • ホイスティングなし(宣言前に使用不可)
  • 周囲の this を使用(最大の違い)
  • より短い構文

現場の合意: ほとんどの場面でアロー関数を使用。クラスメソッド・コンストラクタのみ通常の関数を使用。

引数のパターン

javascript
// 1️⃣ デフォルト値 — 引数を与えない場合、= の後の値が自動的に使用される
const greet = (name = "匿名") => `こんにちは、${name}`;
console.log(greet());         // "こんにちは、匿名"   ← 引数を与えなかったのでデフォルト値を使用
console.log(greet("ホン"));     // "こんにちは、ホン"     ← 引数を与えたのでその値を使用

// 2️⃣ 可変引数 (rest) — いくつかの引数が配列にまとめられる
const sum = (...nums) => nums.reduce((a, b) => a + b, 0);
console.log(sum(1, 2, 3, 4));        // 10
console.log(sum(1, 2, 3, 4, 5, 6));  // 21
console.log(sum());                  // 0   ← 引数がなくてもOK

// 3️⃣ 分割代入 — オブジェクトから必要なプロパティのみを取り出す
const printUser = ({ name, age }) => console.log(`${name} (${age})`);
printUser({ name: "ホン", age: 28 });   // 出力: "ホン (28)"

関数はである

javascript
// 1️⃣ 変数に格納 — 関数も値なので変数に保存可能
const fn = () => "hi";
console.log(fn());   // "hi"

// 2️⃣ 引数として渡す — mapのようなメソッドに関数を"渡す"
const doubled = [1, 2, 3].map(x => x * 2);
console.log(doubled);   // [2, 4, 6]

// 3️⃣ リターン — 関数が関数を返す (クロージャ)
function makeCounter() {
    let count = 0;
    return () => ++count;        // 関数をリターン
}
const counter = makeCounter();
console.log(counter());   // 1
console.log(counter());   // 2
console.log(counter());   // 3   ← count が生きているので継続して増加

これが関数型プログラミングの基盤です。コールバック・高階関数・クロージャはすべてこの上に成り立っています。

純粋関数 (Pure Function) — 推奨パターン

javascript
// ✅ 純粋: 同じ入力 → 同じ出力 + 副作用なし
const double = (n) => n * 2;
console.log(double(3));   // 6   ← 何度呼び出しても同じ入力には同じ出力
console.log(double(3));   // 6

// ❌ 非純粋: 外部状態の変更 (副作用あり)
let count = 0;
const increment = () => { count++; };   // 外部の count を変更する

increment();
increment();
console.log(count);   // 2   ← 呼び出すたびに外部状態が変わる (予測が難しい)

純粋関数のメリット:

  • テストが容易 — 入出力の検証のみ
  • 予測可能
  • 並列処理が安全
  • キャッシュ可能(メモ化)

よくある落とし穴

1. return の書き忘れ:

javascript
const addBad   = (a, b) => { a + b };       // ❌ 中括弧内に return がない
const addGood1 = (a, b) => a + b;           // ✅ 中括弧 X → 式が自動的に返される
const addGood2 = (a, b) => { return a + b; }; // ✅ 中括弧 + return を明示

console.log(addBad(2, 3));    // undefined   ← 🙀 return がないため!
console.log(addGood1(2, 3));  // 5
console.log(addGood2(2, 3));  // 5

2. アロー関数の this:

javascript
const obj = {
    name: "ホン",
    greet: () => console.log(this.name)   // undefined!
};
// アロー関数は独自の this を持たない → 周囲 (グローバル) の this を使用

まとめ

  • アロー関数がモダンな標準
  • 関数は — 渡す・返す・保存することができる
  • 純粋関数が安全なパターン
  • デフォルト引数・rest・分割代入を積極的に活用する

⚡ 実際に試してみよう — 4つの関数 + デフォルト値 · rest

4つの関数の書き方と引数パターンを一度に実行して結果を比較してみましょう。
✏️ JS 코드
📟 コンソール出力
▶ 実行ボタンを押してください
⚠️ ブラウザのサンドボックスで実行 — console.log()のみ対応、alert/fetchは不可

🤖 AIへのプロンプト例

このレッスンの概念を理解すれば、AIに具体的に指示できます。曖昧な「直して」ではなく、語彙を持ったリクエスト — それがトークン節約の出発点です。

  • 「この関数宣言をアロー関数に変換して、this バインディングの違いを確認して」
  • 「この関数を純粋関数にリファクタリングして(副作用を除去して)」
  • 「この関数に適切なデフォルト引数 + 分割代入を適用して」

なぜトークンが減るのか

概念を知らないと、AIの回答を受け取るたびに「それって何ですか?」と聞き直す必要があります。その「聞き直し」がトークンを消費します。概念を一度身につけておけば、会話が一度で完結します。

先に読むとよい概念: 型変換と等価比較
次のおすすめ: アロー関数
関数の基礎 - JavaScript