JavaScript - 原則シリーズ日常の開発では、既存のプロジェクトを引き継ぐときは常に、まず他の人が書いたコードを確認するようにしています。誰かがかっこいいコードを書いているのを見ると、いつもため息をついてしまいます。こんなに美しく簡潔なコードを書く才能はどうやって培ったのですか? どうすれば大物と同じレベルに到達できるでしょうか?さて、これ以上前置きはせずに、今日の話題に入りましょう。 1. 実行コンテキスト簡単に言うと、[実行コンテキスト] とは、JavaScript コードが解析され実行される環境の抽象的な概念です。JavaScript で実行されるすべてのコードは、その実行コンテキスト内で実行されます。 JavaScript コードを実行する場合、コードを実行する必要があるときはいつでも、コードは最初に環境 (ブラウザー、Node クライアント) に入り、次にその環境の実行コンテキストが作成されます。これにより、スコープの決定、グローバルおよびローカル変数オブジェクトの作成など、コードを実行する前にいくつかの準備が行われます。 実行コンテキストの分類
これはデフォルトの最も基本的な実行コンテキストです。どの関数にも含まれていないコードは、グローバル実行コンテキストにあります。 それは次の 2 つのことを行います:
関数が呼び出されるたびに、その関数の新しい実行コンテキストが作成されます。各関数には独自の実行コンテキストがありますが、関数が呼び出されたときにのみ作成されます。プログラムには任意の数の関数実行コンテキストが存在できます。新しい実行コンテキストが作成されるたびに、一連のステップが特定の順序で実行されます。これについては、この記事の後半で説明します。
実行コンテキスト数の制限(スタックオーバーフロー)実行コンテキストは複数存在できます。明確な数制限はありませんが、スタックで割り当てられた領域を超えるとスタックオーバーフローが発生します。これは、終了条件がなく、無限ループが発生する再帰呼び出しでよく発生します。 サンプルコードは次のとおりです。 // 自分自身を再帰的に呼び出す function foo() { 関数 foo(); } 関数 foo(); // エラー: 捕捉されない RangeError: 最大呼び出しスタック サイズを超えました ヒント: JSは「シングルスレッド」であり、一度に1つのコードのみを実行します。 2. 実行スタックJS の実行スタックは、他のプログラミング言語では「コール スタック」とも呼ばれ、コードの実行時に作成されるすべての実行コンテキストを格納するために使用される LIFO (後入れ先出し) データ構造を持つスタックです。 JavaScript エンジンが最初にスクリプトに遭遇すると、グローバル実行コンテキストが作成され、それが現在の実行スタックにプッシュされます。エンジンは関数呼び出しに遭遇するたびに、その関数の新しい実行コンテキストを作成し、それをスタックの一番上にプッシュします。 エンジンは、実行コンテキストがスタックの最上部にある関数を実行します。関数の実行が終了すると、実行コンテキストがスタックからポップされ、制御フローは現在のスタック内の次のコンテキストに到達します。 スタックデータ構造 では、コードを使って実行スタックを理解してみましょう。 a = 'Hello World!' とします。 関数first(){ console.log('最初の関数内'); 2番目(); console.log('再び最初の関数内'); } 関数 second() { console.log('2番目の関数内'); } 初め(); console.log('グローバル実行コンテキスト内'); 次の図は、上記のコードの実行スタックです。 上記のコードがブラウザに読み込まれると、ブラウザの JavaScript エンジンはグローバル実行コンテキストを作成し、それを現在の実行スタックにプッシュします。関数呼び出しが発生すると、JavaScript エンジンは関数の新しい実行コンテキストを作成し、それを現在の実行スタックの一番上にプッシュします。 2 番目の 創造段階 JavaScript コードが実行される前に、実行コンテキストは作成フェーズを経ます。作成フェーズでは次の 3 つのことが起こります。
したがって、実行コンテキストは概念的に次のように表されます。 実行コンテキスト = { ThisBinding = <この値>, レキシカル環境 = { ... }, 変数環境 = { ... }, } このバインディング: グローバル実行コンテキストでは、 関数実行のコンテキストでは、 foo = { baz: 関数() { console.log(これを); } } foo.baz(); // 'this' は 'foo' を参照します。なぜなら 'baz' はオブジェクト 'foo' で呼び出されるからです。let bar = foo.baz; bar(); // 'this' は参照オブジェクトが指定されていないため、グローバルウィンドウオブジェクトを参照します 語彙環境 ES6の公式ドキュメントでは、語彙環境を次のように定義しています。
簡単に言えば、語彙環境は識別子と変数のマッピングを保持する構造です。 (ここで、識別子は変数/関数の名前を参照し、変数は実際のオブジェクト (関数型オブジェクトを含む) またはプリミティブ データへの参照です)。 現在、LexicalEnvironment 内には、(1) EnvironmentRecordant と (2) outerEnvironment への参照という 2 つのコンポーネントがあります。
語彙環境には 2 つの種類があります。
環境ロガーにも 2 つの種類があります (上記のとおり)。
要するに
知らせ 関数環境の場合、宣言型環境レコーダーには、関数に渡される 抽象的には、語彙環境は擬似コードで次のようになります。 グローバル実行コンテキスト = { 語彙環境: 環境レコード: { タイプ:「オブジェクト」、 // バインド識別子をここに記述します } 外側: <null> } } 関数実行コンテキスト = { 語彙環境: 環境レコード: { タイプ:「宣言型」、 // バインド識別子をここに記述します } 外側: <グローバルまたは外部関数環境参照> } } 可変環境: これは、実行コンテキスト内の変数宣言ステートメントによって作成されたバインディングを環境レコーダーが保持するレキシカル環境でもあります。 前述のように、変数環境も語彙環境であるため、上で定義した語彙環境のすべてのプロパティを持ちます。 ES6 では、LexicalEnvironment コンポーネントと VariableEnvironment の違いの 1 つは、前者は関数宣言と変数 ( 上記の概念を理解するために、いくつかのサンプル コードを見てみましょう。 a = 20;const b = 30;var c; とします。 関数 multiply(e, f) { var g = 20; return e * f * g;} c = 乗算(20, 30); 実行コンテキストは次のようになります。 グローバル実行コンテキスト = { ThisBinding: <グローバル オブジェクト>、 語彙環境: 環境レコード: { タイプ:「オブジェクト」、 // ここで識別子 a をバインドします: < 初期化されていません >、 b: < 初期化されていません >、 乗算: < 関数 > } 外側: <null> }, 変数環境: { 環境レコード: { タイプ:「オブジェクト」、 // ここで識別子 c をバインドします: undefined、 } 外側: <null> } } 関数実行コンテキスト = { ThisBinding: <グローバル オブジェクト>、 語彙環境: 環境レコード: { タイプ:「宣言型」、 // ここで識別子をバインドします 引数: {0: 20, 1: 30, 長さ: 2}, }, 外側: <GlobalLexicalEnvironment> }, 変数環境: { 環境レコード: { タイプ:「宣言型」、 // ここで識別子 g をバインド: undefined }, 外側: <GlobalLexicalEnvironment> } } 知らせ 関数実行コンテキストは、関数 これは、作成フェーズでエンジンがコードを検査して変数と関数の宣言を見つけ、関数の宣言は環境に完全に保存されるのに対し、変数は最初は このため、宣言前に これを変数宣言の巻き上げと呼びます。 実行フェーズ これは記事全体の中で最も簡単な部分です。この段階で、これらすべての変数への割り当てが完了し、最終的にコードが実行されます。 知らせ 実行フェーズ中に、JavaScript エンジンがソース コード内で宣言されている実際の場所で 結論はJavaScript プログラムが内部でどのように実行されるかについてはすでに説明しました。優れた JavaScript 開発者になるためにこれらすべての概念を学ぶ必要はありませんが、上記の概念をよく理解しておくと、変数宣言の巻き上げ、スコープ、クロージャなどの他の概念をより簡単に、より深く理解するのに役立ちます。 参考記事: https://juejin.cn/post/6844903682283143181 https://www.jianshu.com/p/6f8556b10379 https://juejin.cn/post/6844903704466833421 JavaScript の実行コンテキストと実行スタックの例に関するこの記事はこれで終わりです。JavaScript の実行コンテキストと実行スタックの詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
>>: MySQL 5.7.17 最新インストールチュートリアル(画像とテキスト付き)
この記事では、アコーディオンを実装するためのjQueryの具体的なコードを参考までに紹介します。具体...
需要シナリオ: 既存の PXC 環境には大量のデータがあります。新しく購入したサーバーをこのクラスタ...
序文Crond は Linux のスケジュール実行ツール (Windows のスケジュールされたタス...
Harbor は、Docker イメージを保存および配布するためのエンタープライズ レベルのレジスト...
ここでは、Jenkins コンテナを例に 3 つの方法を紹介します。方法1コンテナをイメージにパッケ...
目次1. 読みやすいコード1. 統一コード形式2. マジックナンバーを削除する3. 単一機能原則2....
1. まずhello-world.cppファイルを作成しますプログラムコードは次のとおりです。 #i...
1. Linuxサーバーは、/etc/hosts.denyを設定して、相手のIPがSSH経由でサー...
背景:サーバーがFlaskプロジェクトをデプロイし、python3をインストールしたため、再起動時に...
まず、インターネット上の一般的な慣行を見てみましょうデフォルトでは、プライベート ライブラリはイメー...
インストール手順1. 仮想マシンを作成する 2. [カスタム(詳細)]を選択し、[次へ]をクリックし...
目次序文1. ロックとは何ですか? 2. InnoDBストレージエンジンのロック2.1 ロックの種類...
目次序文知る練習すれば完璧になる序文wabpack では、ローダーの他にプラグインがコア機能です。プ...
目次製品要件アイデア問題ライブラリ選択をドラッグコンポーネントを生成する方法コンポーネントを生成する...
MySQL 5.7 以降では、多くのセキュリティ更新が追加されました。旧バージョンのユーザーは慣れて...