クロージャとは
クロージャは関数とその関数が作られた環境という 2 つのものの組み合わせです。
この環境は、クロージャが作られた時点でスコープ内部にあったあらゆる変数によって構成されています。
ざっくり言うと
クロージャとは入れ子関数と、親関数で宣言され入れ子関数から参照されるローカル変数をあわせたもの。
クロージャ
function makeCounter() { // 親関数
let localCounter = 0; // ローカル変数
return function() { // 入れ子関数
localCounter++;
console.log(localCounter);
}
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
counter(); // 3
localCounterの値は保持され、1ずつ増えていく。
これはグローバル変数で
let globalCounter = 0;
function counter() {
globalCounter++;
console.log(globalCounter);
}
counter(); // 1
counter(); // 2
counter(); // 3
としたものと結果は同じだが、グローバル変数を用いなくて済むのでクロージャのほうが安全。
クロージャ
function makeCounter() {
let localCounter = 0;
return function()
localCounter++;
console.log(localCounter);
}
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
counter(); // 3
console.log(localCounter); // エラー
関数の外からは直接ローカル変数localCounterを参照できない。
クロージャが作られるタイミングと独立性
親関数が呼び出されローカル変数と入れ子関数が宣言されたときにクロージャが作られる。
2回親関数を呼び出すと、独立な2つクロージャが作られ、それぞれが参照するローカル変数は同名であるが異なる変数である。
クロージャ
function makeCounter() {
let localCounter = 0;
return function() {
localCounter++;
console.log(localCounter);
}
}
const counter1 = makeCounter(); // クロージャ1ができる
const counter2 = makeCounter(); // クロージャ2ができる
counter1(); // クロージャ1のlocalCount = 1
counter1(); // クロージャ1のlocalCount = 2
counter2(); // クロージャ2のlocalCount = 1