機能(){ VARの I = 0 。 関数B(){ アラート( ++ I)。 } 戻りB。 } VARの C = (); C(); // 1つの C(); // 2 C(); // 3
このコードは2つの特徴があります。
図1に示すように、
関数Aの内部にネストされた関数B
。
図2に示すように、
関数は、関数bを返します。
そうVAR Cを実行した後)(()、変数cはB、Cの関数に実際のポイントにあり、その後、実行= Iのウィンドウ値(1回目)ポップアップ。
実際には、このコードは、関数A内の関数b C参照外部変数の関数であるため、クロージャを作成します。
つまり、関数がクロージャが作成された関数の外に参照される変数Bの内部機能である場合、です。
関数FOO(){ VARの A = 1つの関数FN(){ ++ 。 console.log(A) } 戻りFN() } はconsole.log(FOO)。 FOO(); FOO();
関数FN1(){ VARの A = 1 。 VaRの B = 2 。 関数FN(){ ++ 。 console.log(A) } 戻りFN。 } VAR X = FN1()。 バツ(); バツ(); VAR X = FN1()。 バツ();
一般的に、すべての変数の範囲と機能は、機能の実行の終了時に破壊されます。
閉鎖は今のところ存在しないまでしかし、将来的にクロージャを作成、関数のスコープが開催されます。
関数は、(X){追加 リターン 機能(Y){ 戻り X + Y } } のvar ADD5(5追加します= )。 VaRの ADD10 =(10を追加)。 console.log(ADD5( 2 ))。 console.log(ADD10( 2))。
結果は、それらのメモリの存在だった最後の時間は、リリースされていないので、ベースで同等のプラス2続行
の閉鎖への参照をリリース
ADD5 = NULL;
ADD10 = NULL;
上記のコードとADD5 ADD10から見ることができクロージャです。彼らは、同じ関数定義を共有するが、異なる環境を救いました。
ADD5環境では、xは5です。ADD10において、xは10です。最後にnull参照のADD5と閉鎖のADD10をリリースしました。
オブジェクトが参照されなくなった場合にJavaScriptでは、オブジェクトがガベージコレクション、リサイクルできなくなります。
2つのオブジェクトが相互に参照し、もはや第三者によって参照されない場合、2つのオブジェクトが互いにが回収される参照します。
人生=(LET 関数(){ リターン{ :関数(){ にconsole.log( 'AAAAAA' ) }、 B:関数(){ にconsole.log( 'BBBBBB' ) }、 C:関数(){ コンソール。 (ログ 'CCCCCC' ) } } })() life.a(); life.b();
せ生命= { :関数(){ にconsole.log( 'AAAAAA' ) }、 B:関数(){ にconsole.log( 'BBBBBB' ) }、 C:関数(){ にconsole.log( 'CCCCCC' ) } } life.a()。 life.b();
[コールバック]クロージャとの間の差:
コールバック:
VAR A、 関数A(コールバック){ VAR A = 10 コールバック(); // --------- [注]:関数Bはここで呼び出され、 // それがアクセスを持っていません= 10この値は、 } 関数B(){ IF(=== 10 ){ にconsole.log(A) } 他{ にconsole.log( 'ありがとうございました' ) } } A(B)。
クロージャー:
VaRのA、 関数A(){ VARの A = 10 、関数 B(){ // ----------- Bは、クロージャの関数であり、10 = Aにアクセスすることが可能であるIF(A ==を10 = ){ にconsole.log(A) } 他{ にconsole.log( 'ありがとうございました' ) } } B() } A();