JS の難しさ 同期と非同期、スコープとクロージャ、プロトタイプとプロトタイプ チェーンの詳細な説明

JS の難しさ 同期と非同期、スコープとクロージャ、プロトタイプとプロトタイプ チェーンの詳細な説明

JS スリーマウンテンズ

同期 非同期

フロントエンドで非同期な操作は 2 つだけです。

  • タイマーは非同期に実行されます。
  • ajax 非同期リクエスト

コンパイラ解析 + コード実行の原則:

1. コンパイラはコードを上から下へ1つずつ解析します

2. コードが同期か非同期かを判断する

  • 同期: すぐに実行
  • 非同期: 実行されません。イベントキュープールに入れる

3. 非同期実行を開始する前に、すべての同期実行が完了するまで待機します。

同期と非同期の違い

API: コールバックありの非同期、コールバックなしの同期

パフォーマンス: 非同期のパフォーマンスは良好です (スレッドをブロックしません) 同期はスレッドをブロックします

順序: 同期インオーダー実行、非同期アウトオブオーダー実行

その他: コールバック関数: 関数のパラメータが関数である場合、このパラメータ関数はコールバック関数と呼ばれます。

範囲、終了

関数スコープチェーン

  1. varで宣言された変数のみが関数スコープとして認識されます。
  2. 関数だけが新しい関数スコープを開くことができる
  3. デフォルトのグローバル領域はレベル 0 スコープと呼ばれます。レベル 0 で宣言された関数は、レベル 1 スコープと呼ばれる新しいスコープを開きます。
  4. レベル 1 で宣言された関数はスコープを作成し、レベル 2 のスコープが作成されます。
  5. チェーンのようにスコープチェーンと呼ばれる

ここに画像の説明を挿入

ブロックスコープ

1. {}はブロックレベルのスコープであり、ブロックレベルのスコープを認識する。

2. let の場合、デフォルトのグローバル スコープはレベル 0 ブロック スコープとも呼ばれます。次に、オブジェクトに加えて、中括弧によって新しいブロック スコープが開きます。レベル 0 はレベル 1 を開き、レベル 1 はレベル 2 を開きます。

3. 関数スコープチェーンと同じですが、関数スコープは関数スコープを開く関数のみであり、ブロックスコープはブロックスコープを開く中括弧であり、varは関数スコープを認識し、letはブロックスコープを認識します。

閉鎖

クロージャは関数です。他の関数内の変数を読み取ることができる関数

コード例:

    関数foo(){
      // foo の内部変数 let num = 10
      // この内部はクロージャ関数と呼ばれます inner() {
        コンソール.log(数値)
      }
    }

クロージャの用途は何ですか?

  • クロージャは、外部の世界と関数の内部をつなぐ橋のようなものです。
  • つまり、クロージャを使用すると、外部から関数内の変数にアクセスできるようになります。
クロージャと直接戻り値には違いがある

値を直接返すと、実際にはその値のデータだけが返されます。その後の変更は関数内の変数とは何の関係もありません。

したがって、クロージャを使用すると、外部から関数内の変数に間接的にアクセスできるようになります。

クロージャを書くためのいくつかの方法

簡単に言えば、閉鎖特性を満たすものはすべて閉鎖とみなされる。

クロージャ:関数の内部変数に外部からアクセスできるようにする関数です。

クロージャ効果1: 変数のライフサイクルの延長

ライフサイクル:宣言から破壊までのサイクルを指します

グローバル変数のライフサイクルは、Webページの開始から終了までです。

ローカル変数のライフ サイクルは、それが配置されているスコープ内で開始および終了します。

クロージャは変数のライフサイクルを延長できるため、外部からローカル変数にアクセスできます。

したがって、クロージャを多用するとメモリリークが発生する可能性がある。

メモリ リーク: データの一部は不要になりましたが、まだメモリ領域を占有しており、リサイクルされていません。

解決:

  • クロージャ値をnullに割り当てるだけです
  • null 値を割り当てるということは、誰もそのデータを参照していないことを意味します。誰もそのデータを参照していない場合、そのデータは「ガベージ」としてマークされ、適切なタイミングで GC によってリサイクルされます。
  • GC: ガベージコレクションのメカニズム
  • Chromeブラウザはこのメカニズムを使用しています
閉鎖効果2: アクセス制限

変数をローカル変数にして、外部から直接アクセスできないようにします。

私たちが書いたクロージャ(ブリッジ)を介して間接的にのみアクセスできるため、クロージャ内でいくつかの制限を設けて、アクセスを制限するという目的を達成できます。

閉会の際の注意事項

知らせ:

クロージャを生成する外側の関数が呼び出される回数に応じて、同じ数のクロージャが生成され、そのたびに異なるデータが操作されます。

クロージャを生成する外側の関数が 1 回呼び出されると、生成されるクロージャは 1 つだけになり、操作されるデータは同じままになります。

クロージャはvarの使用によって発生する添え字エラーの問題を解決します

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
  <title>ドキュメント</title>
  <スタイル>
    ul {
      リストスタイル: なし;
      パディング: 0;
      マージン: 0;
    }
    li {
      幅: 30ピクセル;
      高さ: 30px;
      背景色: 黄色;
      行の高さ: 30px;
      テキスト配置: 中央;
      フロート: 左;
      右マージン: 10px;
    }
  </スタイル>
</head>
<本文>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
  </ul>
  <スクリプト>
    // 以前にletはありましたか?いいえ、ではvar // Find all liを使って添え字の問題を解決する方法を見てみましょう
    var lis = document.getElementsByTagName('li')
    (var i = 0; i < lis.length; i++) の場合 {
      // i には変数が 1 つだけあるので、最終的にクリックすると、全員が 1 つの i を訪問します。
      // i の最終値は 5 なので、誰をクリックしても 5 になります
      // 解決法: li が 5 つある場合、5 つの変数が必要で、変数の値はそれぞれ 0、1、2、3、4 です。
      // 5 つの異なる変数を生成するにはどうすればよいでしょうか?関数スコープ(function(){)を作成する必要があります
        // このループは 5 つの自己実行関数を生成するため // これは 5 つの異なるインデックス変数が存在することを意味します // それらの値はそれぞれ 0、1、2、3、4 である必要があり、i の値は正確に 0、1、2、3、4 です
        // iをインデックスに割り当てるだけです var index = i
        // 各liにクリックイベントを追加する lis[i].onclick = function () {
          アラート(インデックス)
        }
      })()
    }
  </スクリプト>
</本文>

</html>

投票機

    // 投票して現在の投票数を取得できる関数を作成する function votor() {
      // チケットの数を格納する変数があります。let ticket = 0
      戻る {
        getTicket: 関数 () {
          console.log('現在のチケット数は: ' + チケット)
        },
        // 投票 add: function () {
          チケット++
        }
      }
    }
    tp = votor() とします
    tp.add()
    tp.add()
    tp.add()
    tp.add()
    tp.getTicket()

閉鎖に関する2つの面接の質問

		// 質問1:
        window.name = "ウィンドウ"; 
        オブジェクトを = {
            名前:「私のオブジェクト」、  
            getNameFunc: 関数 () { 
                関数を返す(){
                    this.name を返します。
                };
            }
        };
        コンソールにログ出力します。  
                 // 質問2:
        window.name = "ウィンドウ";
        オブジェクトを {
            名前:「私のオブジェクト」、  
            getNameFunc: 関数 () { 
                that = this とする; 
                関数を返す(){
                    that.name を返します。
                };
            }
        };
        コンソールにログ出力します。

プロトタイプ、プロトタイプチェーン

プロトタイプオブジェクト

効果:

​ プロトタイプオブジェクトのコンストラクタに共通のプロパティとメソッドを追加すると、メモリを節約できます。

プロトタイプチェーン

どのオブジェクトから始めても、proto に従って上方向に検索することで Object.prototype を見つけることができます。__ __proto__を使用して直列に接続されたオブジェクトのこのチェーンは、プロトタイプ チェーンと呼ばれます。

完全なプロトタイプチェーン図

回路図の前提条件:

各オブジェクトには__proto__属性があり、これはコンストラクター関数のプロトタイプ オブジェクトを指します。

すべてのオブジェクトには、オブジェクトであるprototypeプロパティがあります。

関数もオブジェクトです。

オブジェクトにインスタンス化するための正確なコンストラクターがない場合、そのオブジェクトは組み込みコンストラクターであるとみなされます。

Object のインスタンス。Object のプロトタイプは最上位のプロトタイプ オブジェクトであり、その__protype__nullを指します。

関数はトップレベルのコンストラクターです。これは独自のコンストラクターであり、独自のインスタンス オブジェクトです (簡単に言えば、関数は自分自身を作成し​​ます)。

完成したプロトタイプの概略図:

ここに画像の説明を挿入

以上が、難しいJS同期および非同期スコープ、クロージャプロトタイプ、プロトタイプチェーンの詳細な説明の詳細な内容です。JS同期および非同期スコープ、クロージャプロトタイプ、プロトタイプチェーンの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Javascript のスコープとクロージャの詳細
  • JavaScript スコープ、スコープ チェーン、クロージャの使用方法の詳細な説明
  • JavaScript スコープクローズの詳細な説明
  • JS スコープとクロージャの詳細な理解
  • JavaScript 関数の使用方法の詳細な説明 [関数の定義、パラメータ、バインディング、スコープ、クロージャなど]
  • JS ページはセッション値、スコープ、およびクローズ スタディ ノートを取得します
  • JavaScriptはクロージャを使用してブロックレベルのスコープ操作をシミュレートします
  • JavaScript のスコープとクロージャ

<<:  Docker 接続 MongoDB 実装プロセスとコード例

>>:  MySQL は information_schema オブジェクトの付与をバイパスし、ERROR 1044 (4200) エラーを報告します

推薦する

MySQLクライアント認証後の接続失敗の問題に対する完璧なソリューション

MySQL 環境をローカル (192.168.1.152) にデプロイし、リモート クライアント 1...

Meituan DBデータをデータウェアハウスに同期するアーキテクチャと実践

背景データ ウェアハウス モデリングでは、何ら処理されていない元のビジネス レイヤー データは OD...

HTML のフォームフォームのメソッド属性の紹介

1 メソッドは、データをサーバーに送信する方法を指定するプロパティです。 2 post と get ...

ネイティブ JavaScript メッセージボード

この記事では、参考までにメッセージボードを実装するためのJavaScriptの具体的なコードを紹介し...

Centos7.4 環境に lamp-php7.0 をインストールするチュートリアル

この記事では、Centos7.4 環境に lamp-php7.0 をインストールする方法について説明...

MySQL デッドロック ルーチン: 一意のインデックスの下でのバッチ挿入順序の不一致

序文デッドロックの本質はリソースの競合です。バッチ挿入の順序が一貫していないと、デッドロックに陥りや...

ボタンのタイプが送信として指定されていません。ボタンをクリックしても、指定された URL にジャンプしません。

現在、プロジェクトの要件により、フォームの送信を制御し、送信前にデータを検証および処理するために j...

MySQL全文検索の使用例

目次1. 環境整備2. データの準備3. ショーを始める4. 単語分割エンジン要約する参考文献1. ...

Docker イメージのプルとタグ操作 pull | tag

Fabric プロジェクトのソースコードを読み直してみたところ、Docker の部分でよくわからな...

CSS 要約ノート: 変換、遷移、アニメーションの例

1.移行遷移プロパティの使用法: transition :transition-property t...

Ubuntuが仮想マシンでインターネットに接続できない問題の解決策

インターネットに接続できない仮想マシンをセットアップするのは非常に面倒です。ここでは、Ubuntu ...

Centos6.6 で php7 + nginx 環境をインストールする方法

この記事では、centos6.6 で php7 + nginx 環境をインストールする方法について説...

Linux CDの意味と使い方

Linux CD とはどういう意味ですか? Linux では、cd はディレクトリの変更を意味します...

便利でシンプルなMySQL関数10個

関数0. 現在の時刻を表示するコマンド: select now()。機能: 現在の時刻を表示します。...

フロントエンドフレームワーク Vue における親子コンポーネントデータの双方向バインディングの実装

目次1. 親コンポーネントと子コンポーネント間の一方向の値転送1. 親から子への値の受け渡し2. 子...