JavaScript のクロージャの問題の詳細な説明

JavaScript のクロージャの問題の詳細な説明

クロージャは、純粋関数型プログラミング言語の伝統的な機能の 1 つです。クロージャをコア言語構造の不可欠な部分と見なすことで、JavaScript 言語は関数型プログラミング言語との密接な関係を示します。クロージャは複雑な操作を簡素化できるため、主流の JavaScript ライブラリや高レベルの製品コードでますます人気が高まっています。

1. 変数のスコープ

クロージャを紹介する前に、まず JavaScript の変数スコープを理解しましょう。変数スコープには、グローバル変数とローカル変数の 2 種類があります。

1. グローバル変数

var n = 999; //グローバル変数 function f1() {
        a = 100; //ここでもaはグローバル変数です。alert(n);
    }
    コンソールログ(a); //100

ここで、変数の値は関数の内外で直接取得できます - グローバル変数

2. ローカル変数

//ローカル変数関数f2() {
        var b = 22;
    }
    console.log(b); //エラー

ここで、関数内で定義された値は関数外から直接取得することはできません - ローカル変数

ここで、ローカル変数の値を外部から取得したい場合はどうすればよいでしょうか。
引き続きお読みください:

2. 外部からローカル変数を取得する方法

例を見てみましょう:

var outer = 'Outer'; // グローバル変数 var copy; 
function outerFn(){ // グローバル関数 var inner = 'Inner'; // この変数は関数スコープのみを持ち、外部からアクセスすることはできません function innerFn(){ // innerFn() は outerFn() 内にあります 
 // ここではグローバルコンテキストと周囲のコンテキストの両方を使用できます。
 // 外側と内側にアクセスできます 
 コンソールログ(外側); 
 コンソールログ(内部); 
 } 
 copy = innerFn; // innerFn() への参照を保存します // copy はグローバル コンテキストで宣言されているため、外部から使用できます} 
外側関数(); 
copy(); // innerFn() は直接呼び出すことはできませんが、グローバルスコープで宣言された変数を通じて呼び出すことができます

上記の例を分析してみましょう。変数 outer はグローバル コンテキスト内にあるため、innerFn() 内でアクセスできます。

outerFn()が実行された後、関数への参照をグローバル変数にコピーしてinnerFn()が実行されます。
これはコピーで実現されます。関数 innerFn() が変数コピーを使用して呼び出されると、関数 innerFn() は outerFn() のスコープ内になくなります。では、次のコードは失敗するのではないでしょうか?
コンソールログ(内部);
変数 inner の値は未定義であるはずですよね?ただし、上記のコード スニペットの出力は次のようになります。
「外側」
「内側」

これは JavaScript のチェーン スコープ構造です。子オブジェクトは、すべての親オブジェクトの変数を一度に 1 レベルずつ検索します。したがって、親オブジェクトのすべての変数は子オブジェクトに表示されますが、その逆はできません。

このようにして、関数内でローカル変数を取得できます。

3. 閉鎖の概念

上記のコード ブロック内の copy() 関数はクロージャです。私の理解では、クロージャとは関数内の変数を読み取ることができる関数です。
JavaScript では、関数内のサブ関数を通じてローカル変数を取得できるため、クロージャは関数内で定義された関数として理解できます。
関数の内部と外部をつなぐ橋として理解することができます。

4. 閉鎖の役割

私の意見では、クロージャの役割は主に 2 つの側面に反映されます。

1. 関数内の変数を読み取ることができる

この効果は前のコード ブロックで明確に実証されています。

2. ローカル変数の値はメモリ内に保持できる

ご存知のとおり、ローカル変数は使用されるときにのみメモリ内の一時的な記憶領域を占有し、関数が終了するとその領域は自動的に解放されます。クロージャの出現により、ローカル変数をグローバル変数と同様に一貫してメモリに保存できるようになりました。

        関数c1() {
            var z = 9999;
            nAdd = 関数() {
                1 より大きい
            }

            関数c2() {
                コンソールログ(z);
            }
            c2 を返します。
        }
        var 結果 = c1();
        結果(); //9999
        追加();
        結果(); //10000

上記のコードでは、c1() が 1 回実行され、その時点で z=9999 になります。nAdd() がもう一度実行され、z+1 が作成されます。そして、c1() がもう一度実行され、この時点での z の値 z=10000 が出力されます。これは、z の値は常にメモリに格納され、c1() の最初の呼び出し後に自動的にクリアされないことを意味します。

この時点で、クロージャを使用すると大量のメモリが消費されるので、クロージャを乱用しないように注意する必要があります。関数を終了する前に、未使用のローカル変数をすべて削除します。

JavaScript クロージャの問題の詳細な説明はこれで終わりです。より関連性の高い JavaScript クロージャの問題については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScript の高度なクロージャの説明
  • JavaScript クロージャの説明
  • JavaScript クロージャの説明
  • Javascript のスコープとクロージャの詳細
  • Javascriptのクロージャとアプリケーションの詳細な説明
  • js クロージャとガベージ コレクション メカニズムの例の詳細な説明
  • JS の閉鎖原則とその使用シナリオの分析
  • JavaScriptクロージャの原理と機能の詳細な説明

<<:  Linux\Nginx 環境での仮想ドメイン名の設定とテスト検証

>>:  MySQL でテーブルデータをクリアする 2 つの方法とその違い

推薦する

パーティショニングを使用して数十億のデータに対する MySQL データ処理を最適化する方法

MySQL が数千万のデータをクエリする場合、ほとんどのクエリ最適化の問題はインデックスを通じて解決...

yum 経由で CentOS に PHP をインストールするチュートリアル

まず、yumを使ってCentOSにPHPをインストールする方法を紹介します。 1. PHPのyumソ...

MySQL 5.7.18 マスタースレーブレプリケーション設定(マスター 1 台とスレーブ 1 台)チュートリアルの詳細な説明

1. 複製原理マスター サーバーはバイナリ ログ ファイルに更新を書き込み、ログのローテーションを追...

MYSQL ストアドプロシージャと関数の簡単な記述

ストアドプロシージャとは簡単に言えば、これは強力で、JAVA 言語のメソッドに似た比較的複雑な論理関...

MySQL の group by に関する簡単な説明

目次1. はじめに2. ユーザーテーブルを準備する2.1 グループ化ルール2.2 グループの使用2....

CSS3 を使用して楕円軌道の回転を実装するサンプルコード

最近、次のような効果を達成する必要がある最初は、CSS3D回転を使用して記述すると、次の効果しか得ら...

MySqlのインストールとアンインストールに関する詳細なチュートリアル

この記事では、MySqlのインストールとアンインストールのチュートリアルを参考までに紹介します。具体...

JavaScript データ構造 双方向リンクリスト

単方向リンク リストは、先頭から末尾、または末尾から先頭への方向のみを走査できます。そのため、単方向...

一般的な MySQL 関数の例の概要 [集計関数、文字列、数値、時刻と日付の処理など]

この記事では、よく使用される MySQL 関数について説明します。ご参考までに、詳細は以下の通りです...

Dockerでホストファイルをカスタマイズする方法について簡単に説明します

目次1. コマンド2. docker-compose.yml 3. Dockerファイル4. 直接変...

Vue は水の波紋効果のクリックフィードバック指示を実装します

目次水波効果実装を見てみましょう水の波紋のデフォルトスタイルをカスタマイズする水の波紋の位置と直径を...

オブジェクト内のフィールドを削除する js メソッド

この記事では主に、オブジェクト内のフィールドを削除するための js の実装を紹介し、次のように共有し...

JS でページのスクリーンショット機能を実装する方法

「ページのスクリーンショット」は、ページポスターの生成、ポップアップ画像の共有など、フロントエンドで...

Vue の高度なコンポーネント機能コンポーネントの使用シナリオとソースコード分析

目次導入使用シナリオソースコード分析要約する導入Vue は、コンポーネントをステートレスかつインスタ...

Vue で eslint 検出をオフにする方法 (複数の方法)

目次1. 問題の説明2. 問題解決1. 問題の説明Vue プロジェクトを開発する場合、作成時に誤って...