ホームページ > 記事 > ウェブフロントエンド > フロントエンド開発が知っておくべきJSクロージャとアプリケーション_JavaScriptスキル
「フロントエンド開発者が知っておくべき JS プロトタイプと継承」の記事で、クロージャに関する記事を書くと書きましたが、最近、クロージャ アプリケーションの機能を強化する必要があることに気づいたので、この記事を延期することはできません。もっと長く。この記事では関数クロージャについて説明しており、オブジェクト クロージャ (with の使用など) については説明しません。私の言ったことは間違っていると思われる場合は、お気軽にコメントしてアドバイスをください。
1. クロージャの理論
まず、次の概念を理解する必要があります。
実行環境
関数が呼び出されるたび (関数が呼び出されるとき)が実行されると)、システムは関数の閉じられたローカル実行環境、つまり関数の実行環境を作成します。関数は、ローカル変数、関数パラメータの読み書き、内部ロジックの実行など、常に独自の実行環境で実行されます。実行環境を作成するプロセスには関数のスコープの作成が含まれており、関数も独自のスコープ内で実行されます。別の観点から見ると、各関数実行環境にはスコープ チェーンがあり、子関数のスコープ チェーンには親関数のスコープ チェーンが含まれます。スコープとスコープチェーンについては以下を参照してください。
スコープ、スコープチェーン、呼び出しオブジェクト
関数スコープは字句スコープと動的スコープに分かれています。
レキシカルスコープは関数定義時のスコープ、つまり静的スコープです。関数が定義されると、その字句範囲が決定され、関数構造の入れ子関係に基づいて関数の範囲が記述されます。このとき、関数のスコープチェーンが形成されます。スコープ チェーンは、これらのスコープをネストされた階層関係で接続します。関数の内部 [[scope]] 属性は、このスコープ チェーンを指します。
動的スコープとは、関数呼び出しが実行されるときのスコープです。関数が呼び出されるとき、関数内の [[scope]] 属性は最初に関数のスコープ チェーンを指し、次に呼び出しオブジェクトが作成され、呼び出しオブジェクトは関数パラメーターとローカル変数を記録するために使用されます。関数を作成し、ドメイン チェーンの先頭に置きます。動的スコープは、呼び出し元のオブジェクトをスコープ チェーンの先頭に追加することによって作成されます。このとき、[[scope]] は定義時にスコープ チェーンを持つだけでなく、呼び出し時に呼び出し元のオブジェクトも作成されます。つまり、実行環境のスコープは、関数の定義時に決定されたスコープ チェーンに、関数によって作成されたばかりの呼び出しオブジェクトを加えたものと等しく、新しいスコープ チェーンが形成されます。したがって、これは動的スコープであり、スコープ チェーンもそれに応じて変化します。ここでスコープを見ると、実際にはオブジェクト チェーンです。これらのオブジェクトは、関数が呼び出されたときに作成される呼び出しオブジェクトと、その上の最上位のグローバル オブジェクトまでの呼び出しオブジェクトです。
たとえば、グローバル環境の関数 A に関数 B がネストされている場合、関数 B のスコープ チェーンは、関数 B のスコープ -> 関数 A のスコープ -> グローバル ウィンドウのスコープになります。 。関数Bが呼び出された場合、識別子を探す際には、関数Bのスコープ→関数Aのスコープ→グローバルウィンドウのスコープに従って検索されます。実際には、呼び出しに従って検索されます。関数Bのオブジェクト→関数Aの呼び出しオブジェクト→グローバルオブジェクトの順で検索されます。つまり、関数が呼び出されるとき、関数のスコープ チェーンは実際には呼び出し元のオブジェクト チェーンになります。
クロージャ
動的実行環境では、データはリアルタイムで変化します。これらの非永続変数の値を維持するために、これらの動的データを格納するキャリアとしてクロージャを使用します。以下の文を当てはめるとよく理解できるでしょう)。クロージャの定義: いわゆる「クロージャ」とは、多くの変数とこれらの変数にバインドされた環境を持つ式 (通常は関数) を指します。つまり、これらの変数も式の一部です。
クロージャは関数内にネストされた内部関数であり、内部関数はすべてのローカル変数、パラメータ、および外部関数で宣言された他の内部関数にアクセスできます。内部関数が外部関数の外部で呼び出される場合、クロージャが生成されます。 (実際には、どの関数もグローバルスコープの内部関数であり、グローバル変数にアクセスできるので、ウィンドウのクロージャになります)
例えば、以下の例: