2011-08-03 15 views
3

インナー(プライベート)関数とクロージャの相違点は、非常に似ていると思われますか?インナー(プライベート)関数とクロージャ

インナー機能:閉鎖が通常の範囲の過去のローカル変数の寿命を持続しながら、

function a(param) { 
    function b(theinput) { 
     return theinput * 2; 
    }; 
    return 'The result is ' + b(param); 
}; 

閉鎖

function f() { 
    var b = "b"; 
    return function() { 
     return b; 
    } 
} 

答えて

4

2番目の例では、関数オブジェクト内の変数へのリンクを保持する関数オブジェクトを明示的に返します。最初の例は、単にprivate関数を呼び出した結果を返します。したがって、2番目の例はクロージャです。

はここで、より良いが閉鎖を示し、あなたの第二の例を少し変更したバージョンです:

function f(){ 
    var a = "foo"; 

    // return an object containing two methods 
    // which can access and modify the private "a" 
    // variable even after the function has returned 
    return { 
     showA: function() { 
      alert(a); 
     }, 
     changeA: function(str) { 
      a = str; 
     } 
    } 
} 

var fun = f(); 
fun.showA(); // "foo" 
fun.changeA("blahblah"); 
fun.showA(); // "blahblah" 

フィドル:あなたが見ることができるようにhttp://jsfiddle.net/MKD6p/1

スタックフレームは、後に割り当てが解除されていません関数が返されました。内部の変数は有効に保たれ、適切なインタフェースを使用して再生することができます。

あなたの最初の例の内部機能は、その外側のスコープへのアクセス権を持っている、とは変数に基づいて値がその外側の関数/スコープで宣言リターン/ 閉鎖を行いん。しかし、関数またはモジュールが返されていないので、関数の局所変数は、(外部)関数が戻ったときに割り当て解除されるので、内部関数は外部スコープを持つ閉包を形成しますが、実際にはクロージャが何であるかの生産的な例。

2

インナーファンクションは、ネストされた関数呼び出しです。

2

MDNは言う:

あなたが関数内にネスト機能をすることができます。入れ子にされた(内部)関数は、それを含む(外側の)関数に対してプライベートです。それはクロージャーを形成する。

クロージャは、フリー変数とその変数をバインドする環境(式を「閉じる」)を持つことができる式(通常は関数)です。

ネストされた関数はクロージャであるため、ネストされた関数は、その関数を含む関数の引数と変数を "継承"できます。つまり、内部関数には外部関数のスコープが含まれています。

を内側関数が外側の関数内のステートメントからのみアクセスすることができる。要約する

内部関数はクロージャを形成します。内部関数は外部関数の引数と変数を使用できますが、外部関数は内部関数の引数と変数を使用できません。

+0

ネストされた関数がクロージャ* befroe *を生成するかどうかについて多くの議論がありました*外部関数が終了しました。内部関数は単にスコープチェーン上に外部関数を持ち、その時点ではクロージャは存在しないと主張することができる。内部関数が変数に割り当てられ、外部関数が実行を完了した後に呼び出し可能またはアクセス可能である*場合、終了があります。また、割り当てられた関数が実際にスコープチェーン上の「クローズドオーバー」変数を使用している場合にのみ、クロージャが形成されると考えるユーザーもいます。 – RobG

2

これらは両方とも機能の点で似ています。内部/非公開関数は、可視性が制限されている関数です。クロージャは、周囲のスコープをキャプチャする関数です。

function example() { 
    var window = { 'location': null }; 
    var maybeARedirect = function() { 
     window.location = "http://google.com"; 
    } 
    maybeARedirect(); 
} 

function() {}構築物は単に無名関数を作成した場合は、windowはグローバルオブジェクトを参照することになり、これはGoogleにユーザーをリダイレクトします:ここで説明するためのサンプルコードです。しかし、クロージャを作成するので、ローカル変数windowオブジェクトに変数を設定するだけで効果はありません。

匿名機能を持つほとんどの言語では、少なくともクロージャとして機能することができます。

関連する問題