クロージャー
レキシカルスコープの変数を関数が使用している状態
プライベート変数
関数の外部からアクセスさせないようにする
case
- 数字をカウントアップさせていく関数があったとする。
- 1が3回出力され、カウントアップされない。
- 実行するたびに変数numが初期化されてしまうから。
increment();
increment();
increment();
function increment(){
let num = 0; //初期化
num = num + 1;
console.log(num)
}
>>> 1
>>> 1
>>> 1
- increment関数の外側でnumを初期化すればよい。
let num = 0 //初期化
increment();
increment();
increment();
function increment(){
num = num + 1;
console.log(num)
}
>>> 1
>>> 2
>>> 3
- しかし、変数の上書きも容易にできるので、予期せぬエラーが発生することがある。
let num = 0 //初期化
increment();
increment();
increment();
function increment(){
num = num + 1;
console.log(num)
}
num = 0
increment();
>>> 1
>>> 2
>>> 3
>>> 1
結論
クロージャを使用して解決する。
- クロージャーにあたるincrementFactoryを作成しそこで変数を定義
- incrementFactoryの下層にincrement関数を定義してあげることで外部から変数へのアクセスを制御することができる。
function incrementFactory(){
let num = 0 //初期化
function increment(){
num = num + 1;
console.log(num)
}
return increment;
}
const increment = incrementFactory();
increment();
increment();
increment();
>>> 1
>>> 2
>>> 3
動的な関数の生成
- addNumberFactoryというクロージャに引数を渡す
- addNumberFactoryを初期化する時に引数をわたし、内部で実行するaddNumberに異なる値を渡すことによって動的な関数を生成することができる。
function addNumberFactory(num){
function addNumber(value){
return num + value
}
return addNumber;
}
const add5 = addNumberFactory(10)
const add2 = addNumberFactory(10)
console.log(add5(5))
console.log(add2(2))