JavaScriptのスコープとクロージャ
スコープ
スコープとは変数や関数の有効範囲のことで、グローバルスコープとローカルスコープがあります。
グローバルスコープの中の変数や関数はプログラム内どこででも参照できますが、ローカルスコープの中の変数や関数はその関数内でしか参照できません。
var a = 1; //グローバル変数
function fun(){
var a = 2; //ローカル変数
return a;
}
alert(a); //1が表示
alert(fun()); //2が表示
関数の中と関数の外では中が優先されて、もしその変数がなければ、外に探しに行く、これがスコープチェイン。つまり、var a=2がなければreturn aの結果は1である。
ただし、var a = 2で、varがない場合はグローバル変数。あくまで、関数内でvarをつけた変数がローカル変数。
関数aのなかに関数bを定義する際、中の関数bはローカル関数(変数)として、その関数a内でしか生きられません。
var a = 1;
function f(){ //グローバル関数
function g(){ //ローカル関数
var a = 2
return a;
}
var h = new Function(“”,”alert(a);”);
h(); //Functionコンストラクタ内の関数はグローバルオブジェクトのスコープを参照するので、1になる
}
f(); //2
g(); //スコープ外なので実行不可
クロージャ
function clo(init) {
var cnt = init;
return function() {
return ++cnt;
}
}
var a = clo(10);
alert(a()); // 11
alert(a()); // 12
alert(a()); // 13
上記のようなやつをクロージャという。
function clo(init) {
var cnt = init;
var b = function() {
cnt++;
return cnt;
}
return b; //リターンのあとに関数来るときは()はつけない。
}
var a = clo(10);
alert(a()); // 11
alert(a()); // 12
alert(a()); // 13
としても同じ。要するに関数の戻り値が関数であるということが大切。
実行されると、initが10として、cntが10に、内部関数内で+1されて、11がリターンされる。そのローカル関数をリターンbした結果を、変数aに入れる。
var aで定義された変数の中身は、bという関数自体であり、2回目に実行したときは、var cntで10が再定義されるも、内部function内のcntは11の状態で保持されているので、スコープチェインの原則に従って、うちを優先させると、11に+1して12が返る。その上の階層のcnt=10は結果的に破棄される。
ちなみに、関数内の関数は、クラス定義(var a = function(b,c){};)のときはメソッドとして、関数宣言のときはreturn bのように呼び出す必要がある。
- 参考・引用元
コメントor補足情報orご指摘あればをお願いします。
- << 前のページ
- 次のページ >>
