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ご指摘あればをお願いします。
- << 前のページ
- 次のページ >>