クロージャとは、関数と、その関数を囲む(レキシカルな)スコープの変数への参照とをひとまとめにしたものです。クロージャがあるおかげで、内側の関数は外側の関数がすでに return した後でも外側の関数の変数にアクセスし続けられます。
js
() {
count = ;
{
: ++count,
: count,
};
}
a = ();
b = ();
a.(); a.();
b.();
クロージャとは、関数と、その関数を囲む(レキシカルな)スコープの変数への参照とをひとまとめにしたものです。クロージャがあるおかげで、内側の関数は外側の関数がすでに return した後でも外側の関数の変数にアクセスし続けられます。
() {
count = ;
{
: ++count,
: count,
};
}
a = ();
b = ();
a.(); a.();
b.();
count は外部からアクセスできません。見えるのは inc/get だけです。これがクロージャによって実現されるデータのプライバシーです。さらに makeCounter() を呼び出すたびに、新しく独立したスコープが作られます。
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0); // prints 3, 3, 3 — all share one `i`
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0); // prints 0, 1, 2 — `let` is per-iteration
}
var の場合、すべてのコールバックが同じ i(コールバックが実行される時点では 3 になっている)をクロージャに取り込みます。let は反復ごとに新しいバインディングを作ります。
クロージャはモジュールのプライバシー、メモ化、カリー化、状態を覚えておくイベントハンドラ/コールバックを支えており、React のフック(useState)がレンダー間で値を保持する仕組みもまさにこれです。