JavaScriptの変数は、ローカルやグローバルのスコープに属することができます。
グローバル変数は、クロージャを使ってローカル(プライベート)にすることができます。
グローバル変数
function
では、以下のように、関数内で定義されたすべての変数にアクセスできます。
Example
var a = 4;
return a * a;
}
Try it Yourself ”
しかし、function
は次のように、関数の外で定義された変数にもアクセスできます。
Example
function myFunction() {
return a * a;
}
Try it Yourself ”
先ほどの例では、aはグローバル変数です。
Webページでは、グローバル変数はウィンドウオブジェクトに属します。
グローバル変数は、ページ内(およびウィンドウ内)のすべてのスクリプトで使用(および変更)することができます。
最初の例では、a はローカル変数です。
ローカル変数は、それが定義されている関数の内部でのみ使用できます。
ローカル変数は、その変数が定義されている関数内でのみ使用でき、他の関数や他のスクリプトコードからは隠されています。 一方を変更しても、もう一方は変更されません。
宣言キーワードなしに作成された変数(var
let
const
)は、たとえ関数内で作成されたとしても、常にグローバルです。
変数の寿命
グローバル変数は、別のページに移動したり、ウィンドウを閉じたりして、ページが破棄されるまで有効です。
カウンターのジレンマ
例えば、何かを数えるための変数を使用し、そのカウンターをすべての関数で使用できるようにしたいとします。
グローバル変数を使用し、カウンターを増やすために function
を使用することができます。
Example
var counter = 0;
//カウンタを増加させる関数
function add() {
counter += 1;
}
// add()を3回呼び出す
add();
add();
add();
// カウンタは3になるはずです
Try it Yourself ”
上記の解決策には問題があります。 ページ上の任意のコードが、add()を呼び出さずにカウンターを変更できてしまうのです。
カウンタは add()
関数にローカルなものにして、他のコードが変更できないようにする必要があります。
Example
var counter = 0;
//カウンタを増加させる関数
function add() {
var counter = 0;
counter += 1;
}
//add()を3回呼び出す
add();
add();
add();
//カウンターは3になるはずです。
Try it Yourself ”
ローカルカウンタの代わりにグローバルカウンタを表示しているため、うまくいきませんでした。
グローバル カウンタを削除し、関数に返させることでローカル カウンタにアクセスできます。
Example
function add() {
var counter = 0;
counter += 1;
return counter;
}
//add()を3回呼び出す
add();
add();
//カウンタは3になるはずです。
Try it Yourself ”
うまくいかなかったのは、関数を呼び出すたびにローカルカウンターをリセットしているからです。
JavaScriptの内部関数を使えば、この問題を解決できます。
実際、JavaScriptでは、すべての関数は「その上」のスコープにアクセスできます。
JavaScriptは入れ子になった関数をサポートしています。
JavaScriptは入れ子になった関数をサポートしており、入れ子になった関数はその「上」のスコープにアクセスできます。
この例では、内側の関数 plus()
counter
変数にアクセスできます。
Example
var counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}
Try it Yourself ”
これで、plus()
関数に外部からアクセスできれば、カウンターのジレンマを解決できたかもしれません。
また、counter = 0
を一度だけ実行する方法を見つける必要があります。
クロージャが必要です。
JavaScriptのクロージャ
自己起動型の関数を思い出してください。 この関数は何をするものでしょうか?
Example
var counter = 0;
return function () {counter += 1; return counter}
})();
add();
add();
add();
//カウンタは3になりました
Try it Yourself ”
例の説明
変数 add
は自己起動型関数の戻り値に割り当てられています。
自己起動型の関数は一度だけ実行されます。
このようにしてaddは関数になります。 素晴らしい」のは、親スコープのカウンタにアクセスできることです。
これをJavaScriptのクロージャと呼びます。
カウンタは匿名関数のスコープで保護されており、add関数を使ってのみ変更できます。
クロージャとは、親関数が閉じた後でも、親のスコープにアクセスできる関数のことです。