[JavaScript] 猿でもわかるクロージャ超入門 4 関数を返す関数
<script>
//サンプル4-1
function outer(){
var inner = function (){ // 無名関数を定義してinnerに代入
alert("hello");
}
return inner; // inner関数を返す
}
var f = outer(); // outre関数は戻り値としてinner関数を返す。それがfに代入される。
f(); // "hello"と表示。inner() が実行されたのと同じ効果がある。
</script>
outer関数が実行されると、
- outer内で無名関数が生成される
- それが変数innerに代入される
- そのinnerが戻り値として返される
- それがfに代入される
「関数を返す関数」
となっています。
「お母さんの胎内から赤ん坊が生まれて、"F"と名づけられ、"F"が"おぎゃあ"と泣いた」みたいな感じです。(変?)
同じことをやるのに、何通りかの書き方があります。
普通に関数を宣言してそれを返す
<script>
//サンプル4-2
function outer(){
function inner(){ // inner関数を定義
alert("hello");
}
return inner; // inner関数を返す
}
var f = outer(); // inner関数がfに代入される。
f(); // "hello"と表示。
</script>
function inner( )という風に関数innerを宣言しておきながら、return innerという風にinnerを変数のように扱っていて、実に気持ちが悪いですね。innerは関数でもあり、変数でもあるのです。Javscriptにおける関数の2面性をよく表しています。
無名関数を定義してそのままreturnする
<script>
//サンプル4-3
function outer(){
return function (){ // 無名関数を定義してすぐreturn
alert("hello");
};
}
var f = outer(); // onter内で定義した無名関数がfに代入される。
f(); // "hello"と表示。
</script>
この例では、innerという文字が登場しません。無名関数を使うとコードがとてもすっきりしますね。
さて、"hello"という文字列を事前に準備してみましょう。 上のサンプル4-3と本質的に何ら変わりないコードです。
<script>
//サンプル4-4
function outer(){
return function (){
var x = "hello";
alert(x);
};
}
var f = outer();
f(); // "hello"と表示。
</script>
では次に、var x = "hello"の位置をちょっと外にずらしてみましょう。
<script>
//サンプル4-5
function outer(){
var x = "hello";
return function (){
alert(x);
};
}
var f = outer();
f(); // "hello"と表示。
</script>
問題なく"hello"と表示されましたね。実は、これがクロージャなんです。
クロージャデビュー、おめでとう!!\(^o^)/
これであなたはクロージャを90%理解したことになります。
あと1歩!
次の記事 猿でもわかるクロージャ超入門 5 クロージャを作る
カテゴリ:
JavaScript
closure