var result=f1();调用了函数f1,也就创建了一个栈,保存了n=999,并返回了f2。之后你再怎么调用result(),其实都是在调用同一个f2,而这个f2引用的外部栈,自然还是第一次调用f1时候创建的那个。同样的nAdd はグローバルに動作しますが、同じスタック内のデータにもアクセスします。
つまり、nAdd がグローバル変数であるために n がグローバル変数に昇格するのではなく、nAdd が指す関数と返すクロージャは基本的に同じデータにアクセスします。
var result=f1(): f1 関数は f2 関数を返します 返された f2 関数を結果グローバル変数に割り当てます (f2 のスコープ チェーンは結果グローバル変数に保存されます)
result(): クロージャを形成する result() を呼び出します: は別の関数スコープ内の変数にアクセスする権利を持っています f2 のスコープは f1 のローカル変数 n を参照しているため、f1 が実行されると最後にガベージ コレクションが実行されますメカニズムは、変数 n が結果内でまだ参照されていることを検出したため、ガベージ コレクション メカニズムは n を解放しません。 そのため、n は常に結果スコープチェーンに保存されます。 result のスコープ チェーンは通常、f1 のローカル変数 n にアクセスし、クロージャを形成します。
js は関数呼び出しごとにスタックを作成するため、関数内の関数もこのスタックにアクセスできます。
まずは呼び出します
nAdd
,是因为你没加var
,等于是在函数调用时定义了一个全局作用域下的nAdd
,你加上var
このように書くとエラーが報告されます。var result=f1();
调用了函数f1
,也就创建了一个栈,保存了n=999
,并返回了f2
。之后你再怎么调用result()
,其实都是在调用同一个f2
,而这个f2
引用的外部栈,自然还是第一次调用f1
时候创建的那个。同样的nAdd
はグローバルに動作しますが、同じスタック内のデータにもアクセスします。つまり、nAdd がグローバル変数であるために n がグローバル変数に昇格するのではなく、nAdd が指す関数と返すクロージャは基本的に同じデータにアクセスします。
次のように書き換えてみてください。 リーリー
このコードでは、結果は実際にはクロージャ f2 関数です。これは 2 回実行され、1 回目の値は 999、2 回目の値は 1000 でした。これは、関数 f1 のローカル変数 n が常にメモリに格納され、f1 が呼び出された後に自動的にクリアされないことを証明します。
なぜこれが起こっているのですか?その理由は、f1 が f2 の親関数であり、f2 がグローバル変数に割り当てられているため、f2 は常にメモリ内に存在し、f2 の存在は f1 に依存するため、f1 は常にメモリ内にあり、削除されないためです。呼び出しが完了すると、ガベージ コレクション メカニズム (ガベージ コレクション) によってリサイクルされます。
このコードでもう 1 つ注目すべき点は、「nAdd=function(){n+=1}」という行です。まず、var キーワードが nAdd の前に使用されていないため、nAdd はローカル変数ではなくグローバル変数です。次に、nAdd の値は匿名関数であり、匿名関数自体もクロージャであるため、nAdd は関数の外部で関数内のローカル変数を操作できるセッターと同等です。
http://www.ruanyifeng.com/blo...
違う
n
被提升为全局变量了,这就是闭包。。。。是
nAdd
是全局变量。nAdd
和result
中涉及的n
都是var n = 999
那个n
,而没有全局的n
http://zonxin.github.io/post/...
var nAdd = ... もう一度試してみると、その理由がわかります
var宣言がない場合はグローバル変数に昇格します
変数nはグローバル変数ではありません。このように書くだけではnのメモリは解放されません
f2 関数は、f1 関数内のローカル変数 n への永続的な参照を持ちます。f2 が戻った後、n は解放されません。また、nAdd はグローバル関数として、もちろん n に対して操作できます。
ローカル変数 n の演算は常に関数 f1 で実行されるため、
n はローカル変数のままです。 nAdd() はグローバル関数であり、実行されると、それが属するスコープ内の n が 1 ずつ増加します
var result=f1(); 呼び出されると、ガベージ コレクションのメカニズムにより、f1 が完了すると内部関数 f2 が返され、外部関数の変数 n が参照されます。 nはリサイクルされていません。result()が2回目に実行されると、nは1000になります
nグローバル変数を追加します。varは追加されないため、グローバルスコープになります
nはローカル変数です
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 を出力しますこれは私の理解です、間違いがあればお知らせください
n はグローバル変数ではなく、クロージャです。 n が変更されるのはなぜですか? nAdd の前に var を記述しておらず、デフォルトではグローバルになっていますが、関数はクロージャ内で定義されており、スコープなどはすべてその中にあるためです。