クロージャは JavaScript の重要な概念です。初心者にとって、クロージャは非常に抽象的な概念であり、実際の経験がなければ、定義から理解するのは困難です。したがって、この記事ではクロージャの概念について長々と説明するのではなく、数分でクロージャを学習できるように実践的な情報に直接進みます。
1. 終わり-愛の初体験
新しいテクノロジーに出会ったとき、私が最初にすることは、そのデモ コードを探すことです。コード作成者にとって、コードは自然言語よりも物事を理解できることがあります。 実際、クロージャはどこにでもあります。たとえば、jQuery と zepto の主要なコードはすべて大きなクロージャに含まれています。これにより、脳内でクロージャを生成できるようになります。
function A(){ function B(){ console.log("Hello Closure!"); } return B; } var c = A(); c();//Hello Closure!
これは史上最もシンプルなクロージャーです。どんなにシンプルであっても、これはもうクロージャーではありません。
予備的な理解をした後、「大勢の群衆」の中で「彼女」を一目で認識できるように、通常の機能とどのように異なるのかを簡単に分析してみましょう。
上記のコードは次のように自然言語に翻訳されます:
これらの 5 つのステップを意味のない文に要約すると、次のようになります。
関数 A の内部関数 B が関数 A の外部の変数 c によって参照されています
このナンセンスを再処理すると、クロージャの定義になります:
内部関数がその外部関数の外部の変数によって参照される場合、クロージャが形成されます。
この定義を覚えようとしないでください。この定義を説明する目的は、上記の 5 つのステップがクロージャの定義を詳しく説明するためのものであることを理解していただくことです。
したがって、上記の 5 つの手順を実行すると、すでにクロージャが定義されています。
これで終了です。
2. クロージャーの役割
クロージャの役割を理解する前に、まず 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
count は A の変数で、B ではその値が変更されます。関数 B が実行されるたびに、count の値は元の値に基づいて 1 ずつ増加します。したがって、A のカウントは常にメモリに保持されます。
これは、モジュール内でそのような変数を定義する必要がある場合があります。この場合、この変数をメモリ内に保持する必要がありますが、グローバル変数を「汚染」しないようにする必要があります。この場合、クロージャを使用して定義できます。このモジュール。
3. 高級書き込み
上記の記述方法は実際には最も単純で最も原始的な記述方法ですが、実際のアプリケーションでは、特に一部の大規模な JS フレームワークではこの方法を行う人はいません。なぜこのような書き方をするのかというと、気が散る要素が少ないほど、一つのことに集中しやすくなるからです。以下では、一般的に使用される記述方法を使用して、簡単なデモ コンポーネントを記述します。
(function(document){ var viewport; var obj = { init:function(id){ viewport = document.querySelector("#"+id); }, addChild:function(child){ viewport.appendChild(child); }, removeChild:function(child){ viewport.removeChild(child); } } window.jView = obj; })(document);
このコンポーネントの機能は、コンテナを初期化し、そのコンテナにサブコンテナを追加するか、コンテナを削除することです。この関数は非常に単純ですが、ここには関数を即時に実行するという別の概念が関係しています。 簡単に理解してください。重要なことは、この記述メソッドがクロージャ関数をどのように実装するかを理解することです。
上記のコード構造は 2 つの部分に分けることができます: (function(){})() 赤い部分は式であり、この式自体は匿名関数であるため、この式の後に () を追加することは、この匿名を実行することを意味します。関数。
したがって、このコードの実行プロセスは次のように分解できます:
var f = function(document){ var viewport; var obj = { init:function(id){ viewport = document.querySelector("#"+id); }, addChild:function(child){ viewport.appendChild(child); }, removeChild:function(child){ viewport.removeChild(child); } } window.jView = obj; }; f(document);
このコードにはクロージャの影が見えますが、f に戻り値がありません。このコードに注意してください。
window.jView = obj;
obj は f で定義されたオブジェクトであり、このオブジェクト内で一連のメソッドが定義されています。 window.jView = obj を実行すると、ウィンドウ グローバル オブジェクトに変数 jView を定義し、この変数を obj オブジェクト、つまりグローバルにポイントすることになります。変数 jView は obj を参照し、obj オブジェクト内の関数は f の変数 viewport を参照するため、f の viewport は GC によってリサイクルされず、メモリに保存されるため、この書き方はクロージャーの条件を満たします。
4. 簡単なまとめ
これはクロージャの最も単純な理解です。もちろん、クロージャにはさらに深い理解があり、JS 実行コンテキスト (実行コンテキスト)、アクティブ オブジェクト (呼び出しオブジェクト)、およびその動作メカニズムを理解する必要があります。スコープとスコープチェーン。しかし、初心者としては、今はこれらを理解する必要はありません。簡単に理解した後、実際のプロジェクトで使用することで、自然とクロージャの理解が深まります。
以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。