【くろーじゃ】

クロージャ とは?

💡 関数が「生まれた場所の記憶」を持ち続ける仕組み
📌 このページのポイント
クロージャ:変数を閉じ込める 外側の関数 makeCounter() let count = 0 内側の関数(返される) count++ {'// countにアクセス'} return count 参照 return 内側の関数 外側の関数は終了したが... クロージャ count: 0 内側の関数 使用例: {'counter() → count=1 を返す'} {'counter() → count=2 を返す'} {'counter() → count=3 を返す'} countは外側の関数が終了後も保持される クロージャ = 関数 + その関数が作られた環境(スコープチェーン)
クロージャの仕組み
ひよこ ひよこ

クロージャって普通の関数と何が違うの?

ペンギン先生 ペンギン先生

関数が「定義された場所の変数」を覚えていることだよ。例えば関数の中に関数を書いて、内側の関数が外側の変数を使うと、外側の関数が終わっても内側の関数はその変数を持ち続ける。

ひよこ ひよこ

どんなときに使うの?

ペンギン先生 ペンギン先生

カウンターが典型例だよ。「count = 0」を外側に持ち、内側の「increment」関数がそれを増やす。incrementを返すと、呼ぶたびにcountが増え続ける。外から直接countにはアクセスできないプライベートな状態が作れる。

ひよこ ひよこ

コピーじゃなくて参照って?

ペンギン先生 ペンギン先生

クロージャが変数の「入れ物」を参照しているということ。ループ内でクロージャを複数作ると、全部が同じiを参照してしまって意図しない結果になるのは有名なバグパターンなんだ。letとvarでループの挙動が違う原因もここにある。

ひよこ ひよこ

じゃあletを使えば解決するの?

ペンギン先生 ペンギン先生

そう。letはブロックスコープなのでループのたびに新しい変数の「入れ物」が作られる。varはループ全体で同じ変数を共有するからクロージャが全部同じ値を見てしまう。クロージャとスコープの関係を理解していないと、この違いはなかなかピンとこないんだよ。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
クロージャって出てきたら「変数を閉じ込めた関数」と思えばだいたいOK!
📖 おまけ:英語の意味
「Closure」 = 閉包・閉じること
💬 変数を「閉じ込める(close over)」ことからクロージャ。数学の「閉包」の概念に由来する
← 用語集にもどる