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ご指摘あればをお願いします。

(件名or本文内でキーワード検索できます)



  • << 前のページ
  • 次のページ >>
ページトップへ