2016-07-02 2 views
0

閉鎖の例を分析したいが、私の推論が正しいかどうかわからないので、もし誰かが私に正しいと知らせることができるかどうか疑問に思っている。閉鎖の例の分析

var gLogNumber, gIncreaseNumber, gSetNumber; 
function setupSomeGlobals() { 
    // Local variable that ends up within closure 
    var num = 42; 
    // Store some references to functions as global variables 
    gLogNumber = function() { console.log(num); } 
    gIncreaseNumber = function() { num++; } 
    gSetNumber = function(x) { num = x; } 
} 

setupSomeGlobals(); 
gIncreaseNumber(); 
gLogNumber(); // 43 
gSetNumber(5); 
gLogNumber(); // 5 

var oldLog = gLogNumber; 

setupSomeGlobals(); 
gLogNumber(); // 42 

oldLog() // 5 

[OK]をラインsetupSomeGlobals();に、我々は3つのメソッドを含んでいる私たちの関数を呼び出すようにします。

次に、gIncreaseNumber();と呼びます。クールなので、今すぐnum - > 43、それから私たちはそれを記録し、期待通りに43を得る!

今は物事が退屈になっているので、numを別の値に設定してください。行番号gSetNumber(5);に今すぐnum = 5と5と言ってください。もちろん、ログには5が記録されます。

ここで物事はトリッキー私のために得るheres。だから、この変数をoldLogに、glogNumberと同じプロパティを持つメソッドを与えるようにしましょう。さて、十分に公正。

だから我々は

(OK、これは私はわからないんだけど何である) setupSomeGlobals()を呼び出し、そして私たちは、コードが戻っ var num = 42になるので、以前に上書きされます数を増やすと番号を設定するようにしましたすべてのもの

gLobNumber()の場合は42となります。なぜなら、私の推論では、すべてが最初にリセットされるからです。var num = 42です。ニース!

oldLog()となっており、gLogNumberを指しています。これはsetupSomeGlobals()でしたが、すべてがリセットされてから42になるはずですが、これは5を出力します。 Erm whats何が起こっていますか?

+2

'setupSomeGlobals()'を呼び出すと、 'num'変数は変更されません。独自の' num'変数を持つ新しいクロージャが作成されます。 'oldLog'は上書きされません。以前の' gLogNumber'関数への参照はまだ保持されています。これは以前の閉包を使用しています。 – nnnnnn

+0

私はoldLog = gLobNumberを設定してからsetupSomeGlobals()を呼び出す前にしました。私はsetupSomeGlobalsを呼び出す前にoldLogが5を指していたので、そのプロパティを上書きしませんでしたか? –

+1

'oldLog'は' 5'を直接指しません。 'num'変数が '5'である最初のクロージャにアクセスできる関数を指します。 'setupSomeGlobals()'の各呼び出しは、3つのグローバル変数が参照するものだけを上書きします。 (ちなみに、実際には「プロパティ」ではありません。オブジェクトにはプロパティがあります。この場合は関数を参照する変数です) – nnnnnn

答えて

0

これは、あなたがsetupSomeGlobalsと呼ばれるsetupSomeGlobals()

var oldLog = gLogNumber; 

内部関数への参照()関数(gLogNumber、などが...)再作成しまった二時間を設定するための閉鎖が何であるかを正確に今では新しい番号にアクセスできるようになりました。これは、setupSomeGlobals()が初めて呼び出されたときにoldLogが変数にアクセスできるようになりました。

閉鎖チェックの詳細については、John Reisgのチュートリアルを参照してください。

+0

「その時点でのその時点の値」ではなく、値が変更される可能性のある変数の参照です。(インクリメントとセットの関数を呼び出すことで示されているように) – nnnnnn