JavaScriptをやるなら誰もが通るであろう鬼門をなんとなく解説👀
●クロージャとは?
クロージャとは「自分を囲むスコープ内にある変数を参照可能な関数」と定義できます。
●じゃあスコープってなに?
スコープとは「変数を参照できる範囲」です。
スコープの種類を詳しく見ていきましょう。
●スコープの種類
❶グローバル変数
関数の外(トップレベル)にある変数のスコープ。
varで宣言すると、関数及びブロックの内外関係なくグローバル変数となります
//グローバル変数
var global = "Hello";
function func(){
//関数内からアクセス可
console.log(global); // ⇨ Hello
}
//関数外からアクセス可
console.log(global); // ⇨ Hello
❷ローカル変数
グローバル変数以外の全ての変数のスコープ。
下記2種類存在します。
(1)関数スコープ
関数内で宣言されている変数のスコープ。関数外からはアクセスできない。
function func(){
//関数スコープ変数
const local = "Hello";
//関数内からアクセス可
console.log(local); // ⇨ Hello
}
//関数外からアクセス不可
console.log(local); // ⇨ Uncaught ReferenceError: local is not defined
(2)ブロックスコープ
{}内で宣言された変数のスコープ(if{}など)。{}外からはアクセスできない。
function func(){
const num = 4;
if (num % 2 === 0) {
//ブロックスコープ変数
const result = "偶数";
//関数内からアクセス可
console.log(result); // ⇨ "偶数"
}
//ブロック外からアクセス不可
console.log(result); // ⇨ Uncaught ReferenceError: result is not defined
}
//関数外からアクセス不可
console.log(result); // ⇨ Uncaught ReferenceError: result is not defined
●クロージャの重要性
グローバル変数の説明を見ると一見、「便利じゃね?」と思うかも知れない。
でもそこにはリスクが伴う。予期せぬ変数の上書きなどの発生原因になる。
function func(elem){
//関数スコープ変数(変更したくないもの)
let origins = 25;
return {
sum: () => elem + origins,
negative: () => elem - origins
};
}
console.log(func(50).sum()); // ⇨ 75
console.log(func(50).negative()); // ⇨ 25
//スコープ外で変数を上書きしようとするとエラー
origins = 30; // ⇨ origins is not defined
●まとめ
このようにクロージャとスコープは密接に関係しています。
ややこしいですが、「便利そうだから」と言って無闇にグローバル変数を使わず
常にスコープを意識してコーディングしましょう。
予期せぬエラーや、誤った変数の変更を防止すると共に、無駄なデバッグを撲滅できます。
これを機に、スコープと友達になろう!