VUE3.0 をすぐに始める方法: 学習に入る
関連する推奨事項: JavaScript チュートリアル
「実行環境」、「スコープ」、「プロトタイプ (チェーン)」、「実行コンテキスト」などをよく耳にすると思います。これらは何を表しているのでしょうか?
js は型指定が弱い言語であり、変数の型は実行時にのみ決定されることがわかっています。 JSエンジンはJSコードを実行すると、さらに字句解析、構文解析、意味解析などの処理を上から下へ実行し、コード解析が完了するとAST(抽象構文木)を生成し、最終的にマシンコードを生成します。 CPU が AST に基づいて実行して実行できること。
さらに、JS エンジンはコードの実行時に他の処理も実行します。たとえば、V8 には 2 つのステージがあります。
これにより、次のようになります。 「実行コンテキスト」と「スコープチェーン」の 2 つの概念。
上記のことから、js コードが実行可能コードの一部を実行すると、対応する実行コンテキストが作成されることがわかります。
まず、jsの実行コードに相当する概念として「実行環境」、つまりグローバル環境、関数環境、 eval
があります。
次に、各実行コンテキストには 3 つの重要な属性があります
2
つのコードを見てみましょう。
var スコープ = "ローカル スコープ"; 関数 f(){ 戻りスコープ; } return f();}checkscope();
varscope="グローバルスコープ";function checkscope(){ var スコープ = "ローカル スコープ"; 関数 f(){ 戻りスコープ; } return f;}checkscope()();
何を出力するのでしょうか?
なぜ?答えは、実行コンテキスト スタックが異なるということです。
最初に「実行コンテキストスタック」とは何ですか?
実行コードを実行する際には、事前に準備を行います。この「準備」を専門的には「実行コンテキスト」と呼びます。しかし、関数などの実行可能コードが増加するにつれて、非常に多くの実行コンテキストをどのように管理すればよいでしょうか?そこで、JS エンジンは実行コンテキスト スタックの概念を作成しました。
配列を完全に使用してその動作をシミュレートできます (スタックの一番下には常にグローバル実行コンテキスト globalContext があります)。
EStack=[globalContext];
として EStack を定義し
、次に最初のコード部分をシミュレートします
。Push
(
<checkscope> functionContext); EStack.push(<f> functionContext);EStack.pop();EStack.pop();
2 番目のコードは次のようになります。
EStack.pop();EStack.push (<f> functionContext);EStack.pop();
その理由は、最初に「クロージャ」の概念を勉強する必要があるからです。
ところで、「フロントエンドのモジュール化」において「長期データ保存」を実現するにはどうすればよいでしょうか?
キャッシュ?いいえ。閉鎖!
まず、スコープとは、変数が定義されるプログラム内の領域を指します。スコープは変数の検索方法を指定し、現在実行中のコードの変数へのアクセス権を決定します。
スコープには、静的スコープと動的スコープの 2 種類があります。
JSで使用される静的スコープは「レキシカルスコープ」とも呼ばれます。関数のスコープは、関数の定義時に決定されます。
上記のことから、字句スコープ内の変数は、コンパイル プロセス中に特定のスコープを持つことになります。このスコープは「現在の実行コンテキスト」です。 ES5 以降では、スコープの代わりに「レキシカル環境」を使用して実行コンテキストを記述します。字句環境は 2 つのメンバーで構成されます。
例を見てみましょう:
var value=1 ;関数 foo(){ console.log(value);}関数 bar(){ 変数値=2; foo();}bar();
上記の定義を振り返ると、何を出力する必要があるでしょうか?
実行プロセスを分析してみましょう。
foo() 関数を実行します。まず foo 関数内を検索して、ローカル変数値があるかどうかを確認します。そうでない場合は、定義時の位置、つまり value=1 に基づいて上位層のコードを検索します。そのため、結果は 1 として出力されます。
もちろん、これはそれほど単純ではなく、実行コンテキストの観点から分析することもできます。
上では、字句環境の 2 つのコンポーネント (スコープ) について説明しました。実行コンテキストと組み合わせると、外部の語彙環境の参照を通じてスコープをスタックに沿って層ごとに拡張し、現在の環境から外側に広がるチェーン構造を確立できることを見つけるのは難しくありません。
別の例を見てみましょう:
function foo(){ コンソール.ディレクトリ(バー); 変数a=1; 関数 bar(){ a=2; }}console.dir(foo);foo();グローバル関数 foo は
、
静的スコープから、独自の[[scope]]
foo[[scope]]=[globalContext] の [[scope]] 属性を作成します。
( )内には、続いてfoo関数の定義期間と実行期間にも入ります。 FOO関数の定義期間中、ファンクションバーの[[scope]]
には、グローバルな組み込みスコープとFOOバーの組み込みスコープが含ま
れ
ます
この点: 「JS は外部字句環境参照を渡します。変数オブジェクトのスコープ チェーンを作成するために使用されます。これにより、実行環境がアクセスできる変数と関数への順序付けされたアクセスが保証されます。」
実行コンテキストでの質問に戻りましょう。先ほども言いましたが、これらの違いは何でしょうか? なぜ同じように「ローカル スコープ」を出力するのかについて話しましょう。「JS は字句スコープを使用し、関数のスコープは関数が作成される場所に依存します」という文と同じです。 - JS関数の実行 関数定義時に作成されるスコープチェーンを使用します。ネストされた関数 f() はこのスコープ チェーンで定義されており、その中の変数スコープは、f() がいつどこで実行されるかにかかわらず、このバインディングは f() の実行時に引き続き有効です。
変数がそれ自体の字句環境レコードで見つからない場合、最も外側の字句環境の外部字句環境参照がnull
になるまで、外部字句環境参照に基づいて外側の層まで変数を検索できます。
これに似たものに、「オブジェクト内のプロトタイプ チェーンに基づく検索」があります。
__proto__
は null)違いも明らかです。プロトタイプ チェーンはプロトタイプ属性を通じてオブジェクトの継承を確立するリンクですが、スコープ チェーンは内部関数が外部関数にアクセスできるようにするクロージャを指します。直接的か間接的かにかかわらず、すべての関数スコープ チェーンは最終的にグローバル コンテキストにリンクします。
関連する推奨事項: JavaScript 学習チュートリアル。
これは、JavaScript エンジンが JS コードを実行する方法について詳しく説明したものです。詳細については、PHP 中国語 Web サイトの他の関連記事に注目してください。