この理解が正しいかどうか、先輩方に確認していただきたいです。
補足: クロージャを初めて実行するときは、上位層の変数を検索する必要があり、それを見つけた後の上位層の変数値が下位層の変数値になるという理解でよいでしょうか。検索は最初の実行時に引き継がれているため、それ自体が独自のものになります。
少し乱雑な感じがします。 。 。
(フェイスカバー
---------------また追加---------------------
続きはこちら「カオスになるほど」を読みました。
その後、完全に混乱してしまいました。
出力結果から判断すると、最初のコンソール出力と最後のコンソール出力では、f1 の n は不変です。
しかし、サブ関数は相互に変数を読み取ることはできないのでしょうか? nAdd の式が f2 の n に影響を与えるのはなぜですか?
PHP中文网2017-05-18 10:51:50
同じ質問があるので、回答をコピーしてさらに追加しました。
var result=f1()
: f1 関数は f2 関数を返します
返された f2 関数を結果グローバル変数に割り当てます (f2 のスコープ チェーンは結果グローバル変数に保存されます)
result()
: クロージャを形成する result() を呼び出します: は別の関数スコープ内の変数にアクセスする権利を持っています
f2 のスコープは f1 のローカル変数 n を参照しているため、f1 が実行されると最後にガベージ コレクションが実行されますメカニズムは、変数 n が結果内でまだ参照されていることを検出したため、ガベージ コレクション メカニズムは n を解放しません。
そのため、n は常に結果スコープチェーンに保存されます。 result のスコープ チェーンは通常、f1 のローカル変数 n にアクセスし、クロージャを形成します。
nAdd()
: nAdd は var を書き込まないため、nAdd() と result() を呼び出すと、クロージャが形成されます。したがって、nAdd=funtion(){n+=1} の場合、この無名関数のスコープ チェーンはクロージャを形成するためにグローバル変数 nAdd に保存され、f1 ローカル変数 n を見つけるために nAdd() が呼び出されます。 =999、スコープ チェーンの n+ 1=1000。
result()
: result() は 1000 を出力します
nAdd(); 3 番目のステップを繰り返します n+1 = 1001
result(); 4 番目のステップを繰り返し、n
f1(); f1 が呼び出されるときにクロージャは形成されません。n は常に 999 です。これは、n が f1 の実行後にガベージ コレクション メカニズムによって破棄されるためです。そのため、ここで var n=999 が再度呼び出されます。 999です
nAdd の式が f2 の n に影響を与えるのはなぜですか?
クロージャのため、nAdd() もクロージャを形成し、n の値を変更したため、後で再び result() が呼び出され、n は破棄されておらず、リサイクルは +1 されています。それは影響力になります。
最後に、f1() が呼び出されるときにクロージャはなく、n は以前に破棄されています。したがって、常に a=999;
これは私の理解です、間違いがあればお知らせください
曾经蜡笔没有小新2017-05-18 10:51:50
複雑すぎて言えません
このクロージャは、js の静的スコープ機能を使用してこの効果を実現します
リーリーresult() の最初の呼び出し:
alert(n) は n1 を探しています
nAdd(); は n1 の値も追加します
後ろの方も同様です
そして最後の f1();
実行時、var n = 999; は n1 に値を割り当てます
console.log(n) の n も n1 なので、出力される値は 999 です
あなたの例は少し単純ですが、複雑な例を見てみましょう (静的スコープの説明に注目してください):
静的スコープ