[JavaScript] 猿でもわかるクロージャ超入門 5 クロージャを作る

クロージャは、理解するよりも作るほうが簡単

前回の記事では、「関数を返す関数」をいじって、いきなりクロージャを作ってしまいました。
こんなやつです。
<script>
//サンプル5-1

function outer(){
    var x = 1;	 // outerのスコープ内で変数を定義

    return function (){ //この関数が「クロージャ」
        alert(x);  // "関数内関数"の中で、outerスコープの変数を参照。
    };

}

var f =  outer(); 
f();  // 1と表示。
</script>
これが何故クロージャなのかというと、次の条件を満たしているからです。
  • outerのスコープ内で変数を定義し、
  • outerの中に関数(=関数内関数)を作って
  • その関数内関数から、先ほどの変数を参照する

何の役に立つのか?

「クロージャが作れたのはいいけど、何がうれしいのか?」
もっともな疑問です。
では、先ほどのをちょっと改造したこんなコードを実行してみてください。
<script>
//サンプル5-2

function outer(){
    var x = 1;

    return function (){
        alert(x);
	x = x + 1;
    };

}

var f =  outer(); 
f();  // 1
f();  // 2
f();  // 3
</script>

あれ?

あれれ?

例の問題が解けちゃいましたね。
問題
 呼び出すたびに、1,2,3,...を返すような関数f()を定義せよ。
f();  //  1 
f();  //  2
f();  //  3
上のコードでは、1回目のf( )が呼び出された後、変数xの値(=2)が捨てられずに保持されます。
そこで2回目のf( )を呼び出すと、先ほどのxの値(=2)を覚えていて、それをalert表示してから、xの値を1増やして3にして、それをまた保持ます。

クロージャを使うと、このように「状態を保持する関数」を作ることができます。
「クロージャはオブジェクトに似ている」というのが実感できたかと思います。

これで、あなたはクロージャを100%理解しました。

次回は、jQueryとクロージャを使って実用的なことをしてみましょう。

次の記事:[JavaScript] 猿でもわかるクロージャ超入門 6 クロージャの使いどころ


補足1 無名関数は必須ではない。

サンプル5-2のコードは、他にもいろいろな書き方があります。
入門3回目で紹介した「無名関数」を使わなくても、クロージャは作れます。
(しかし実際にはクロージャと一緒に使われることが多いので紹介しました。)
「無名関数」を使わないクロージャ
//サンプル5-3

function outer(){
    var x = 1;

    function inner(){
        alert(x);
	x = x + 1;
    };

    return inner;
}

var f =  outer(); 
f();  // 1
f();  // 2
f();  // 3

補足2 「クロージャ」(Closure)という名前について

英和辞典で調べたら「閉鎖」という意味があるそうです。
変数xが、outer関数のスコープ内に閉じ込められて(closed)いて、inner関数以外のどこからも参照できないことに由来するのでしょう(たぶん)。
カテゴリ: