JavaScript クロージャについて質問がありますか?
高洛峰
高洛峰 2017-05-18 10:50:47
0
9
984

変数 n がリセットされないのはなぜですか?

リーリー

変数 n がグローバル変数であることを説明します。変数 n は f2 でグローバル変数に昇格しますか?

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全員に返信(9)
给我你的怀抱

js は関数呼び出しごとにスタックを作成するため、関数内の関数もこのスタックにアクセスできます。

まずは呼び出しますnAdd,是因为你没加var,等于是在函数调用时定义了一个全局作用域下的nAdd,你加上varこのように書くとエラーが報告されます。

var result=f1();调用了函数f1,也就创建了一个栈,保存了n=999,并返回了f2。之后你再怎么调用result(),其实都是在调用同一个f2,而这个f2引用的外部栈,自然还是第一次调用f1时候创建的那个。同样的nAdd はグローバルに動作しますが、同じスタック内のデータにもアクセスします。

つまり、nAdd がグローバル変数であるために n がグローバル変数に昇格するのではなく、nAdd が指す関数と返すクロージャは基本的に同じデータにアクセスします。

次のように書き換えてみてください。 リーリー

いいねを押す +0
我想大声告诉你

このコードでは、結果は実際にはクロージャ 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...

いいねを押す +0
左手右手慢动作

違うn 被提升为全局变量了,这就是闭包。。。。
nAdd是全局变量。
nAddresult中涉及的n 都是 var n = 999那个n,而没有全局的n

http://zonxin.github.io/post/...

いいねを押す +0
仅有的幸福

var nAdd = ... もう一度試してみると、その理由がわかります

var宣言がない場合はグローバル変数に昇格します

変数nはグローバル変数ではありません。このように書くだけではnのメモリは解放されません

いいねを押す +0
给我你的怀抱

f2 関数は、f1 関数内のローカル変数 n への永続的な参照を持ちます。f2 が戻った後、n は解放されません。また、nAdd はグローバル関数として、もちろん n に対して操作できます。

いいねを押す +0
左手右手慢动作

ローカル変数 n の演算は常に関数 f1 で実行されるため、

n はローカル変数のままです。 nAdd() はグローバル関数であり、実行されると、それが属するスコープ内の n が 1 ずつ増加します

いいねを押す +0
阿神
  • var result=f1(); 呼び出されると、ガベージ コレクションのメカニズムにより、f1 が完了すると内部関数 f2 が返され、外部関数の変数 n が参照されます。 nはリサイクルされていません。result()が2回目に実行されると、nは1000になります

  • nグローバル変数を追加します。varは追加されないため、グローバルスコープになります

  • nはローカル変数です

いいねを押す +0
黄舟
  1. var result=f1(): f1 関数は f2 関数を返します
    返された f2 関数を結果グローバル変数に割り当てます (f2 のスコープ チェーンは結果グローバル変数に保存されます)

  2. result(): クロージャを形成する result() を呼び出します: は別の関数スコープ内の変数にアクセスする権利を持っています
    f2 のスコープは f1 のローカル変数 n を参照しているため、f1 が実行されると最後にガベージ コレクションが実行されますメカニズムは、変数 n が結果内でまだ参照されていることを検出したため、ガベージ コレクション メカニズムは n を解放しません。
    そのため、n は常に結果スコープチェーンに保存されます。 result のスコープ チェーンは通常、f1 のローカル変数 n にアクセスし、クロージャを形成します。

  3. nAdd(): nA​​dd は var を書き込まないため、nAdd() と result() を呼び出すと、クロージャが形成されます。したがって、nAdd=funtion(){n+=1} の場合、この無名関数のスコープ チェーンはクロージャを形成するためにグローバル変数 nAdd に保存され、f1 ローカル変数 n を見つけるために nAdd() が呼び出されます。 =999、スコープ チェーンの n+ 1=1000。

  4. result(): result() は 1000 を出力します

これは私の理解です、間違いがあればお知らせください

いいねを押す +0
洪涛

n はグローバル変数ではなく、クロージャです。 n が変更されるのはなぜですか? nAdd の前に var を記述しておらず、デフォルトではグローバルになっていますが、関数はクロージャ内で定義されており、スコープなどはすべてその中にあるためです。

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート