[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回目のf( )が呼び出された後、変数xの値(=2)が捨てられずに保持されます。
呼び出すたびに、1,2,3,...を返すような関数f()を定義せよ。
f(); // 1 f(); // 2 f(); // 3
そこで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関数以外のどこからも参照できないことに由来するのでしょう(たぶん)。
カテゴリ:
JavaScript
closure