javascriptのスコープとクロージャ

javascriptのスコープとクロージャ

スコープ

スコープには、グローバルスコープとローカルスコープがある。

グローバルスコープはプログラム内どこででも参照できるが、ローカルスコープはその関数内でしか参照できない。

var a = 1; //グローバル変数
function f(){
var a = 2; //ローカル変数
return a;
}
alert(a); //1
alert(f()); //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のように呼び出す必要がある。

参考サイト:
http://www.slideshare.net/Lanchester
http://dqn.sakusakutto.jp/2009/01/javascript_1.html
http://www.atmarkit.co.jp/fdotnet/ajaxjs/ajaxjs03/ajaxjs03_04.html

2012年12月13日8:53 PM | カテゴリー: javascript | コメント(0)

コメントを残す

メールアドレスが公開されることはありません。