ホームページ >ウェブフロントエンド >jsチュートリアル >わかりやすいJavaScriptクロージャーのサンプルコード
クロージャ は JavaScript における独特の概念であり、特に ECMA 仕様で与えられている定義は、実践的な経験がなければ、その定義を理解することから始めるのは困難です。 。したがって、この記事ではクロージャの概念について長々と説明するのではなく、数分でクロージャを学習できるように実践的な情報に直接進みます。
1 結論 – 愛の最初の経験 新しいテクノロジーに接したとき、私が最初にすることは、そのデモ コードを見つけることです。コード作成者にとって、コードは自然言語よりも物事を理解できることがあります。 実際、クロージャはどこにでもあります。たとえば、jQuery と zepto の主要なコードはすべて大きなクロージャに含まれています。そこで、脳内でクロージャを生成するのに役立つ、最も単純で最も原始的なクロージャのデモを書きます。function A(){ function B(){ console.log("Hello Closure!"); } return B; } var c = A(); c();//Hello Closure!これは史上最もシンプルなクロージャーです。どんなにシンプルであっても、これはもうクロージャーではありません。 予備的な理解をした後、「大勢の群衆」の中から「彼女」を一目で認識できるように、通常の機能とどのように異なるのかを簡単に分析しましょう。 上記のコードは次のように自然言語に翻訳されます: (1) は通常の関数 A を定義します(2) は A で通常の関数 B を定義します(3) は A で B を返します (正確には、 A の B の参照を返す) (4) A() を実行し、A の戻り結果を変数 c に代入する(5) c() を実行する これら 5 つのステップを意味のない文に要約します:
The関数 A の内部関数 B は、関数 A の外部の変数 c によって参照されています このナンセンスを再処理すると、クロージャの定義になります: 内部関数がその外部関数の外部の変数によって参照されるとき、クロージャが形成されます。 この定義を覚えようとしないでください。この定義を説明する目的は、上記の 5 つのステップがクロージャの定義を詳しく説明するためのものであることを理解していただくことです。 つまり、上記の 5 つのステップを実行すると、すでにクロージャが定義されています。 これで閉店です。 2 クロージャの役割クロージャの役割を理解する前に、まず JavaScript の GC メカニズムを理解しましょう。JavaScript では、オブジェクトが参照されなくなった場合、そのオブジェクトは GC によってリサイクルされます。そうでない場合、オブジェクトは 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();// 3count は 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 で定義されたオブジェクトです。このオブジェクトは一連のメソッドを定義します。これは、ウィンドウ グローバル オブジェクトで変数 jView を定義することを意味します。これを変更すると、変数は obj オブジェクトを指します。つまり、グローバル変数 jView は obj を参照し、obj オブジェクトの関数は f の変数 viewport を参照するため、f の viewport は GC によってリサイクルされず、メモリに保存されるので、この書き方でクロージャの条件を満たします。
これはクロージャの最も単純な理解です。もちろん、クロージャにはさらに深い理解があり、JS の実行コンテキストとアクティブ オブジェクト (呼び出しオブジェクト)、およびスコープの操作メカニズムを理解する必要があります。そしてスコープチェーン。しかし、初心者としては、今はこれらを理解する必要はありません。簡単に理解した後、実際のプロジェクトで使用することで、自然とクロージャの理解が深まります。
以上がわかりやすいJavaScriptクロージャーのサンプルコードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。