序文有能なフロントエンド開発者であるか、または有能なフロントエンド開発者になりたいのであれば、JavaScript コードの実行プロセスを理解し、実行コンテキスト、スコープ、変数の昇格などの関連概念を理解し、それらを自分のコードに巧みに適用する必要があります。この記事は、「JavaScript You Don't Know」、「Advanced JavaScript Programming」、およびいくつかのブログを参照しています。 文章1. JavaScriptコードの実行プロセスに関連する概念js コードの実行は、コンパイラのコンパイルと js エンジンおよびスコープの実行の 2 つの段階に分かれています。コンパイラのコンパイル段階 (プリコンパイル段階) は、単語分割/字句解析、解析/構文解析、コード生成の 3 つの段階に分かれています。 (1)単語分割/字句解析段階では、コンパイラはコードを分割し、文を字句単位のストリーム/配列に分割する役割を担う。 (2)構文解析・字句解析フェーズでは、前フェーズの字句単位ストリームを、プログラムの文法構造に準拠したネストされた要素からなる抽象構文木に変換します。 (3)コード生成フェーズでは、抽象構文木が実行可能コードに変換され、JSエンジンに渡されます。 js コード実行の 3 つの重要な役割: (1)jsエンジン:コード実行の全プロセスを担当 (2)コンパイラ:jsコードの構文を解析し、実行可能なコードを生成する (3)範囲:宣言されたすべての識別子を収集して維持し、特定のルールに従って、宣言された識別子に対する現在のコードのアクセス権を決定します。 2. 実行コンテキストと実行スタックJavaScript コードが実行されるときは常に、実行コンテキストで実行されます。実行コンテキストに関しては、実行スタックが何であるかを知っておく必要があります。他のプログラミング言語の「呼び出しスタック」である実行スタックは、コードの実行時に作成された実行コンテキストを格納するために使用される LIFO (後入れ先出し) データ構造を持つスタックです。 js エンジンは、実行するコードを初めて検出すると、まずグローバル実行コンテキストを作成し、それを現在の実行スタックにプッシュします。エンジンが関数呼び出しを検出するたびに、その関数の新しい実行コンテキストを作成し、それをスタックの先頭にプッシュします。js エンジンは、スタックの先頭にある関数を実行します。関数が実行されると、実行コンテキストがスタックからポップされ、制御フローが次のコンテキストに到達します。各実行コンテキストには、変数オブジェクト、スコープ チェーン、this という 3 つの重要なプロパティが含まれています。これらの特性も十分に理解する必要があります。 2.1 コンテキスト呼び出しスタックvar scope1 = "グローバルスコープ"; 関数 checkscope1(){ var scope1 = "ローカルスコープ"; 関数f(){ コンソールログ(スコープ1); } f() を返します。 } チェックスコープ1(); var scope2 = "グローバルスコープ"; 関数 checkscope2(){ var scope2 = "ローカルスコープ"; 関数f(){ コンソールログ(スコープ2); } f を返します。 } チェックスコープ2()(); 上記のコードスニペットは両方ともローカルスコープを出力します 上記のコードでは、スコープはローカル変数である必要があります。ブロックレベルのスコープを見つけることができます。f() がいつどこで実行されても、このバインディングは f() の実行時に有効です。同じ結果が表示されますが、2 つのコード セグメントの実行コンテキスト スタックの変更は異なります。 最初のコード: push(<checkscope1>functionContext)=>push(<f>functionContext)=>pop()=>pop() 2 番目のコード: push(<checkscope2>functionContext)=>pop()=>push(<f>functionContext)=>pop() 2.2 3種類の実行コンテキスト(1)グローバルな文脈 js エンジンが js コードの解析を開始すると、最初に遭遇するのはグローバル コードです。初期化中に、グローバル実行コンテキストがコール スタックにプッシュされます。実行コンテキスト スタックは、アプリケーション全体が終了するとクリアされます。スタックの一番下は常にグローバル実行コンテキストです。これは、デフォルトまたは基本的なグローバル スコープです。関数内のコードはグローバル スコープ内にあります。最初にグローバル ウィンドウ オブジェクトが作成され、次にこの値がグローバル オブジェクトと同じに設定されます。プログラムには、グローバル実行コンテキストが 1 つだけ存在します。トップレベルの js コードでは、グローバル オブジェクトがドメイン チェーンの先頭であるため、これを使用してグローバル オブジェクトを参照できます。つまり、修飾されていないすべての変数と関数は、このオブジェクトの関数として照会されます。 つまり、グローバル実行コンテキストは 1 つだけであり、これは通常、クライアントのブラウザーによって作成されます。つまり、私たちがよく知っているウィンドウ オブジェクトであり、これを通じて直接アクセスできます。 (2)機能コンテキスト 関数が呼び出されるたびに、その関数の新しいコンテキストが作成されます。各関数には独自のコンテキストがあり、関数が呼び出されたときに作成されます。同じ関数が複数回呼び出されると、新しいコンテキストが作成されることに注意してください。 (3)コンテキスト付きで評価する eval 内および関数を使用して実行されるコードにも独自の実行コンテキストがありますが、JavaScript 開発者は eval をあまり使用しないため、ここでは説明しません。 2.3 実行コンテキスト作成フェーズ 実行コンテキストの作成は、作成フェーズと実行フェーズの 2 つのフェーズに分かれています。 js エンジンは、実行コンテキスト作成フェーズで主に次の 3 つのことを行います。これを決定する ==> 語彙環境コンポーネントを作成する ==> 変数環境コンポーネントを作成する (まだよく理解していません) (1)これを決定するが、詳細は説明しない。 (2)語彙環境コンポーネントを作成する レキシカル環境は、ECMAScript コードのレキシカル ネスト構造に基づいて、識別子と特定の変数および関数との関連付けを定義する仕様タイプです。語彙環境は、環境レコーダーと、外部の語彙環境を参照する空の値(場合によっては)で構成されます。環境レコードは、現在の環境における変数や関数宣言の実際の位置を保存するために使用されます。外部環境導入レコードはわかりやすいです。自分の環境からアクセスできる他の外部環境を保存するために使用されます。こうなると、スコープチェーンの意味が少しあるのでしょうか。 語彙環境には 2 つの種類があります。
(3)可変環境コンポーネントの作成 変数環境は語彙環境とも言えます。語彙環境のすべての特性を持ち、環境記録と外部環境導入も持っています。 ES6 での唯一の違いは、レキシカル環境は関数宣言と let const で宣言された変数を格納するのに使用され、変数環境は var で宣言された変数のみを格納することです。 3. JavaScript スコープとスコープチェーン3.1 範囲レキシカルスコープは、コードの作成時または定義時に決定されますが、動的スコープは実行時に決定されます。(これも同じです) レキシカルスコープは関数が宣言される場所に焦点を当てますが、動的スコープは関数が呼び出される場所に焦点を当てます。 JavaScript はレキシカルスコープを使用しており、そのスコープは、コードの作成時に変数とブロックスコープを記述する場所によって決定されるため、字句解析器がコードを処理してもスコープは変更されません。スコープは、変数が漏洩したり公開されたりすることを防ぐ独立した領域であると理解できます。つまり、スコープの最大の用途は変数を分離することであり、異なるスコープ内の同じ名前の変数間で競合が発生することはありません。 範囲を理解する前に質問を見てみましょう 関数foo(){ console.log(値); } var 値 = 1; 関数バー() { var 値 = 2; console.log(値); 関数 foo(); } バー(); 上記のコードの出力は何でしょうか? まず、グローバル コンテキストで foo() 関数、値変数 (値は未定義)、bar() 関数が宣言されています。コード実行フェーズでは、bar 関数コンテキストがスタックにプッシュされて実行され、値が 2 として出力されます。次に foo() が実行され、foo() がスタックにプッシュされます。値を出力する際に変数が見つからないため、js エンジンは上位スコープ、つまりグローバル スコープを検索し、1 を出力します。関数が実行されると、コンテキストはスタックからポップされます。次の関数を見てみましょう。スコープは階層化されています。内側のスコープは外側のスコープの変数にアクセスできますが、その逆はできません。 ES6 以降、js のスコープは、グローバル スコープ、関数スコープ、ブロック スコープ、およびデセプション スコープに分割されます。 3.1.1 グローバルスコープ コード内のどこからでもアクセスできるオブジェクトにはグローバル スコープがあり、最も外側の関数と最も外側の関数の外側で定義された変数にはグローバル スコープがあり、未定義の変数と直接割り当てられた変数はすべて自動的にグローバル スコープを持つように宣言されます。 3.1.2 関数のスコープ 関数スコープとは、この関数に属するすべての変数が関数全体のスコープ内で使用および再利用できることを意味します (実際には、ネストされたスコープ内でも使用できます)。 3.2 スコープチェーンスコープ チェーンは、基本的に、名前で変数 (識別子名) を検索するための一連のルールです。ルールは非常にシンプルです。変数が自身の変数オブジェクト内で見つからない場合は、親変数オブジェクト内を検索します。最も外側のグローバル コンテキストに到達すると、見つかったかどうかに関係なく検索プロセスは停止します。最初に一致する変数が見つかると検索は停止します。これをシャドウイングと呼びます。 スコープ チェーンの目的は、実行環境がアクセスできるすべての変数と関数への順序立ったアクセスを保証することです。 4. 実行コンテキストとスコープの違いすべての関数呼び出しには、スコープとコンテキストが関連付けられています。基本的に、スコープは機能ベースであり、コンテキストはオブジェクトベースです。言い換えれば、スコープは関数が呼び出されるたびに変数がどのようにアクセスされるかに関するものであり、各呼び出しは独立しています。コンテキストは常にキーワード this の値であり、これは現在実行可能なコードを呼び出したオブジェクトへの参照です。スコープは関数が定義されたときに決定されます。関数内の変数は関数のスコープと関連しており、関数が実行されるスコープも関数が定義されたときのスコープと関連しています。コンテキストは主に、関数の実行時に決定されるキーワード this の値を指します。簡単に言えば、this はこの関数を呼び出す人を指します。 5. 最後以上がjs実行コンテキストとスコープの詳細な概要です。js実行コンテキストとスコープの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: Mac でソースコードから MySQL 5.7.17 をコンパイルしてインストールするチュートリアル
>>: Docker Swarm を使用して分散クローラー クラスターを構築する例
今日は、Docker イメージ、各レイヤーの内容を調べ、Docker/OCI イメージのサイズを縮小...
テーブルを美しくするために、セルごとに異なる境界線の色を設定できます。基本的な構文<TD 境界...
目次序文シナリオ分析要約する序文数日前、友人がWeChatで私に連絡してきて、マシンがダウンタイムか...
画像タグ <IMG> を挿入します。今日私たちが目にするカラフルなウェブページはすべて、...
秘密鍵を開かずにリモート サーバーのデータベースに接続するのは非常に便利です。新しい接続でデータを入...
目次COUNT 関数は何をするのですか? MyISAMの「魔法」シンプルなCOUNT最適化近似値を使...
自社製品にクリック後1~2秒待機時間があるボタン(確認メールを送信する)があるため、クリック後の1~...
この記事では、WeChatアプレットで写真を撮ったり、アルバムから写真を選択したりするための具体的な...
サーバーの画像が他のウェブサイトからホットリンクされると、サーバーの帯域幅とアクセス速度に影響します...
目次前提TypeScript と JavaScriptコードエディタの選択TypeScriptを学ぶ...
目次序文原因を発見するカスタムフィルタリングルール要約する序文インターネットの急速な発展に伴い、情報...
日常業務において、フォームの検証は非常に一般的な設計要件です。ログイン ボックスや登録ボックス、アン...
目次序文React 関数コンポーネントVue (2.x) の機能コンポーネント🌰 例: el-tab...
目次序文: 1. Navicatの紹介2. シンプルなチュートリアルの共有接続管理ライブラリテーブル...
1. Alipay方式: Alipay メソッド: Alipay をクリックして支払い、バックエンド...