JavaScript の高度なクロージャの説明

JavaScript の高度なクロージャの説明

1. 閉鎖の概念

一般的な機能の実行とインスピレーションを見てみましょう。

        関数stop() {
            var 数値 = 0;
            console.log(数値);
        }
        stop(); // num が 0 であることを出力します
        console.log(num); // エラー報告関数が定義されていません

1. この時点では関数内の変数は関数外からアクセスできない

2. 関数内で定義された変数は常に存在するわけではなく、関数が終了すると消えます。

閉鎖の概念:

1. 別のスコープ内の変数にアクセスできる関数です。

2. 別の言い方をすると、内部関数の有効期間が外部関数の宣言有効期間よりも長く、内部関数が何らかの方法で外部スコープからアクセスされる場合、クロージャが作成されるということです。

次のクロージャ コードと説明を見てみましょう。

        関数fn() {
            var 数値 = 10;
            // 関数 fun() {
            // コンソール.log(数値);
 
            // }
            // fun を返します。
            関数を返す(){
                console.log(数値); // 10
            }
        }
        var f = fn();
        関数f();

これをいくつかの部分に分けることができます。

1. fn 関数は内部の戻り値を持ち、関数です。

2. return 関数は内部の num 変数を出力します。 num 変数が出力できる理由は、スコープ チェーンのアクセス メカニズムによるものです。以下では、スコープとスコープ チェーンの知識ポイントを補足します。

3. f変数を使用してfn()を外部的に受け入れます。つまり、fn[内部関数]の戻り値を受け入れます。

4. 次に f が呼び出されます。これは、fn 内の内部関数が呼び出されることを意味します。最終的に10を印刷できる

追加の知識ポイント:

1. 範囲:

変数は特定の範囲内で動作し、この範囲外では効果がありません。この範囲が範囲です。スコープは関数が呼び出されたときではなく、関数が定義されたときに作成されます。

2. スコープチェーン:

一言でまとめると、「内部関数は外部関数変数にアクセスできる」という考え方に基づき、近接原則を採用して、変数をレイヤーごとに検索します。このメカニズムはスコープ チェーンと呼ばれます。

関数 A に関数 B が含まれている場合、関数 B は関数 A の内部関数になります。

内部関数が変数を使用する場合、まずその内部にそのような変数が存在するかどうかを確認します。

そうでない場合は、次のレベルを検索します。[近接の原則]

関数がレイヤーごとに見つからない場合は、最終的にグローバル変数の下で検索されます。

        var a = 1;
        var b = 11;
        関数fn1() {
            var a = 2;
            var b = '22';
            関数fn2();
            関数fn2() {
                var a = 3;
                関数fn3();
                関数fn3() {
                    var a = 4;
                    コンソールログ(a); // 4
                    console.log(b); // '22'
                }
            }
        }
        関数fn1();

3. ガベージコレクションのメカニズム

JS ガベージ コレクション メカニズムに関するこのビッグ ブラザーの説明を参照できます。

//www.jb51.net/article/229425.htm

これら3つの概念を組み合わせて、閉鎖の役割を見てみましょう。

2. 閉鎖の役割:

関数 A を外部関数と呼び、この関数内に関数 B があります。

関数A [関数B]の戻り値を受け取るために外部で変数fを使用する

関数Aのスコープ内の変数はnumと呼ばれます

1. 関数の外部から関数内の変数にアクセスできるようにする [内部スコープへの外部アクセス用のチャネルを構築する]

原則:実際には上記で説明しました。

まず、上に示した一連の動作の原理を理解する必要があります。関数Bは関数Aの変数numを呼び出すことができる

2 番目に理解すべきことは、まず、関数 A の戻り値は関数 B [内部関数] であり、次に、この戻り値は関数外部の変数 f で受け取られる必要があるということです。それを受け取った後、関数 B を呼び出すことができ、関数 B は関数 A の変数 num にアクセスします。そして、この内部関数 B が閉鎖関数です。

2. 関数内の変数のライフサイクルを延長できます。

最初の効果は 2 番目の効果をもたらします。 js 変数にはガベージ コレクション メカニズムがあります。関数が実行されると、変数はクリアされ、メモリが削除されます。ただし、クロージャが使用されている場合、変数はすぐにクリアされない可能性があります。

その理由は、外部変数 f が関数 A の内部関数 B を受け入れ、この内部関数が関数 A のスコープ内の変数 num にアクセスするためです。関数 B が実行され、変数 f が存在する限り、変数 num は常に存在します。関数 A の実行が終了しても消えることはありません。

非常に詳しく解説されているので、以下の記事も参考にしてください。

JavaScript クロージャの説明

3. 閉鎖例

クロージャのいくつかのアプリケーションは後で追加されます。

クロージャをいつ使用するかを覚えておき、乱用しないようにする必要があります。

3.1 liをクリックすると現在のliのインデックス番号が出力されます。

    <ul class="nav">
        <li>ドリアン</li>
        <li>臭豆腐</li>
        <li>ニシンの缶詰</li>
        <li>大きな豚足</li>
    </ul>
    <スクリプト>
        // クロージャの適用 - li をクリックすると、現在の li のインデックス番号が出力されます // 1. 属性を動的に追加するメソッドを使用できます var lis = document.querySelector('.nav').querySelectorAll('li');
        (var i = 0; i < lis.length; i++) の場合 {
            lis[i].onclick = 関数(){
                console.log(i); // 4 つの 4
            }
        }
    </スクリプト>

原理:上の図をこのように書くと、印刷される i は常に 4 になります。その理由は、この時点では非厳密モードになっているからです。非厳密モードでは、for ループは同期実行タスクですが、ボタンのクリックは非同期タスクです。同期実行が完了すると、i に 4 が加算されます。次に、非同期タスクは i を出力しますが、これは常に 4 です。

解決策1: クロージャを使用する

1. forループは4つの即時実行される関数を生成する

2. 即時に実行される関数はクロージャのアプリケーションです。 [クリック コールバック] 関数を含む即時実行関数内のすべての関数は、即時実行関数によって渡されたパラメータを使用できます。

        (var i = 0; i < lis.length; i++) の場合 {
            (関数 (i) {
                // コンソールログ(i);
                lis[i].onclick = 関数(){
                    コンソールにログ出力します。
 
                }
            })(私);
        }

変更2: var--->let

対応する小さな li をクリックし、対応するインデックス番号である i を印刷します。 letの使用はES6構文であり、forはブロックレベルのスコープを持ちます。

        var lis = document.querySelector('.nav').querySelectorAll('li');
        (i = 0 とします; i < lis.length; i++) {
            lis[i].onclick = 関数(){
                // コンソールログ(i);
                コンソールにログ出力します。
            }
        }

方法3: カスタム属性インデックスを設定する方法を使用する

        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) { // これはletではなくvarであることに注意してください
            lis[i].index = i; // これはthis.indexではなくlis[i]であることに注意してください。この時点ではクリックは行われていないので、これはどこから来るのでしょうか?
            lis[i].onclick = 関数(){
                コンソールにログ出力します。
            }
        }

要約する

この記事はこれで終わりです。皆さんのお役に立てれば幸いです。また、123WORDPRESS.COM のその他のコンテンツにも注目していただければ幸いです。

以下もご興味があるかもしれません:
  • JSにおけるクロージャの役割について詳しく話しましょう
  • JavaScriptクロージャの原理と機能の詳細な説明
  • JavaScript クロージャの詳細
  • JavaScript クロージャの説明
  • JavaScriptのクロージャとは何かを学びましょう

<<:  HTMLで細い線のテーブルを作成する簡単な例

>>:  ウェブページの背景画像を伸ばす2つの方法

推薦する

Ubuntu 18仮想マシンのクローン作成後に同じIPアドレスになる問題の解決方法

序文最近、仮想マシンを使用して Ubuntu 18.04 をインストールしました。クローン作成後、I...

Vueバインディングオブジェクトと配列変数を変更した後にレンダリングできない問題の解決策

プロジェクトシナリオ:ページ表示には <ul> タグがあります。リストデータを動的に表示...

VirtualBox でのホストオンリー + NAT モードのネットワーク構成

VirtualBoxのHost Only+NATモードのネットワーク構成は参考用です。具体的な内容は...

CSS 擬似要素::マーカーの詳細な説明

この記事では、CSS ::markerの興味深い疑似要素を紹介します。これを使用すると、テキスト番号...

CSS3 は下部に固定されたフッターを実装します (ページの高さに関係なく常に下部にあります)

序文フッター領域を下部に固定します。ページの高さや幅に関係なく、モバイル メニューと同様に、フッター...

MySQLの手順を完全に削除する

目次1. まずMySQLサーバーを停止する2. MySQLサーバーをアンインストールする3. MyS...

Linux システム ディスクのフォーマットとスワップ パーティションの手動追加

Windows: NTFS、FATをサポートLinux は次のファイル形式をサポートしています: C...

CentOS7 環境で gcc (バージョン 10.2.0) をアップグレードする詳細な手順

目次簡単な紹介1. 現在のgccバージョンを確認する2. gccインストールパッケージ(バージョン1...

Linux での NVIDIA GPU 使用状況の監視の詳細な説明

TensorFlow をディープラーニングに使うとビデオメモリ不足がよく起こるので、GPU 使用状況...

Windows 7 環境での Docker 高速ビルドと Alibaba Cloud コンテナ高速化構成の詳細な説明

前回の Docker に関する記事では、MAC システムでの構築について説明しました。この記事では、...

jsでユーザー登録機能を実装する

この記事の例では、ユーザー登録機能を実装するためのjsの具体的なコードを参考までに共有しています。具...

Nginx SSL証明書設定エラーの解決策

1. はじめにWeb プロジェクトを Linux サーバーで公開する場合、SSL 証明書を構成する必...

CentOS 6.4 MySQL 5.7.18 のインストールと設定方法のグラフィックチュートリアル

Centos6.4 で mysql5.7.18 をインストールするための具体的な手順が全員に共有され...

MySQL query_cache_type パラメータと使用方法の詳細

MySQL クエリ キャッシュを設定する目的は次のとおりです。クエリ結果をキャッシュしておくと、次回...

CentOS 7のインストールと設定方法のグラフィックチュートリアル

この記事は、CentOS 7の詳細なインストールチュートリアルを参考のために記録します。具体的な内容...