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 のその他のコンテンツにも注目していただければ幸いです。 以下もご興味があるかもしれません:
|
序文:前回の記事では、注意深い学生であれば発見できたかもしれない DDL ステートメントの使用法を中...
ストアドプロシージャとは簡単に言えば、これは強力で、JAVA 言語のメソッドに似た比較的複雑な論理関...
この記事の例では、ファイルアップロード機能を実現するためのjquery+springbootの具体的...
1. セレクターを調整するコンビネータを使用すると、セレクターの説明をより正確に記述できます (C...
序文今日、オープンソース プロジェクトのフィードバック フォームを設計していたところ、絵文字表現を挿...
背景ブラウザの互換性の問題を解決するのは非常に面倒なことです。高度な技術はそれほど必要ありませんが、...
1. ドロップダウンリストの例コードは次のとおりです。 <!doctypehtml> ...
IE8には複数の互換モードがあります。 IE プラットフォームの設計者である Chris Wilso...
MySQL は、コミュニティ エディション (コミュニティ サーバー) とエンタープライズ エディシ...
問題の説明MySQL が正常に起動しました。以下に示すように、 ps -ef |grep mysql...
目次継承ES5 プロトタイプ継承ES6 クラス継承両者の違いES5プロトタイプ継承の内部実装ES6 ...
この記事では、Linux yumを使用してmysql5.6をインストールする簡単な手順を参考までに紹...
最近、たまたま vue+springboot のフロントエンドとバックエンドの分離プロジェクトに触れ...
123WORDPRESS.COM では、FileZilla のダウンロード リンクを提供しています:...
最近、docker を学習していたときに、docker コンテナ内のネットワーク状態を照会するために...