ホームページ  >  記事  >  ウェブフロントエンド  >  [JavaScript] クロージャを数秒で理解する

[JavaScript] クロージャを数秒で理解する

王林
王林オリジナル
2024-08-26 21:31:35885ブラウズ

[JavaScript] Understand closures in  seconds

クロージャは JavaScript の基本的な考え方ですが、初心者にとっては曖昧で理解しにくいと感じるかもしれません。特に、ECMA 標準の定義は、実際の経験がなければ理解するのが難しい場合があります。そのため、この投稿ではクロージャの概念を長々と説明するのではなく、実際のコードを使用して理解しやすくします。

1. クロージング

function A(name){
    function B(){
       console.log(name);
    }
    return B;
}
var C = A("Closure");
C();//Closure

これは最も単純なクロージャーです。

基本を理解したので、これが一般的な関数とどのように異なるかを簡単に検討してみましょう。以下は、前述のコードが自然言語に翻訳されるとどのように表示されるかを示します:

  1. 引数名を指定して通常の関数 A を定義します
  2. Aに正規関数Bを定義し、Bでは外部変数名を参照
  3. A で B を返す
  4. A を実行し、結果を変数 C に代入します
  5. C を実行
1 つのステートメントで次の 5 つの操作をカプセル化できます。

関数 A 内の関数 B と変数名は、関数 A の外の変​​数 C によって参照されています。

少し変更を加えると、このステートメントはクロージャを次のように定義します。

内部関数が外部関数の外部の変数によって参照される場合、クロージャが形成されます。

したがって、上記の 5 つの操作を実行するとクロージャが定義されます。

クロージャーの使用法

クロージャーの使用法を理解する前に、JavaScript の GC (ガベージ コレクション) メカニズムを理解しましょう。

JavaScript では、オブジェクトが参照されなくなった場合、そのオブジェクトは GC によって再利用され、それ以外の場合はメモリ内に保持され続けます。

上記の例では、B は A 内で定義されているため、B は A に依存しており、外部変数 C が B を参照しているため、A は C によって間接的に参照されています。

つまり、A は GC によって収集されず、メモリ内に保持され続けます。この推論を証明するために、上記の例を少し改良してみましょう。


function A(){
    var count = 0;
    function B(){
       count ++;
       console.log(count);
    }
    return B;
}
var C = A();
C();// 1
C();// 2
C();// 3
    var C = A(); を呼び出すと、A が実行され、カウント変数と内部関数 B が作成されます。A は B を返すため、C 変数は実際には B への参照を持ちます。その後、関数 B は、 A.
  1. の変数をカウントします。
  2. B はクロージャであるため、関数 B は A の count 変数にアクセスできます。これは、B がクロージャであり、クロージャが作成されたコンテキスト (ローカル変数など) を保存するためです。
  3. C() が呼び出されるとき、実際には関数 B が呼び出されます。C() が呼び出されるたびに、B は count の値をインクリメントし、その値をコンソールに表示します。
  4. A の実行コンテキストは B が作成されると終了しますが、B がそのローカル変数 (count など) を参照している限り、A のローカル変数は再利用されません。
  5. B が参照されなくなった場合にのみ、A のカウント変数とその他のローカル変数が回復されます。この例では、C は依然として B を参照しているため、count の値は回復されず、A の実行コンテキストも回復されません。

カウントがリセットされないのはなぜですか?

開閉機構:

    クロージャは count の状態を保持し、内部関数 B からアクセスできるようにします。A の実行コンテキストが終了しても、B はこの状態を参照し続けるため、count の状態はメモリ内に残ります。
  • B への各呼び出し: C() への各呼び出しは、実際には B() への呼び出しであり、クロージャに保存されているカウントを使用し、再初期化はしません。
したがって、モジュール内でいくつかの変数を定義し、これらの変数をメモリ内に保持したいが、グローバル変数を「汚染」したくない場合は、クロージャを使用してこのモジュールを定義できます。

以上が[JavaScript] クロージャを数秒で理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。