[JavaScript] 猿でもわかるクロージャ超入門 4 関数を返す関数

Javascriptでは、「関数を返す関数」というものを作れます。
<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関数が実行されると、
  1. outer内で無名関数が生成される
  2. それが変数innerに代入される
  3. そのinnerが戻り値として返される
  4. それがfに代入される
このとき、outer関数は
「関数を返す関数」
となっています。

「お母さんの胎内から赤ん坊が生まれて、"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 クロージャを作る

カテゴリ: