ホームページ  >  記事  >  ウェブフロントエンド  >  Javascript の実行コンテキストについて説明する記事

Javascript の実行コンテキストについて説明する記事

青灯夜游
青灯夜游転載
2023-02-14 19:41:062375ブラウズ

この記事では、JavaScript の実行コンテキストについて説明し、思考の質問を共有します。思考の質問の分析を通じて、実行コンテキストについての理解がさらに深まることでしょう。

Javascript の実行コンテキストについて説明する記事

これまでの記事では、実行コンテキストの 3 つの重要なメンバー、変数オブジェクト、スコープ チェーン、this について詳しく理解しました。まず4つの記事の内容をまとめて、散在していた知識を集約し、シンプルにまとめました。前回の記事からここに来た人がいるかわかりませんが、前回の記事で疑問が残りました。その疑問を分析することで、実行コンテキストをより深く理解していきます。

思考の質問

ケースを少し複雑にするために、いくつかの修正が加えられていますが、元の質問で検討された点は変更されていません。

function func(value){
    getValue = function(){
        console.log(value);
    };
    return this
}
            
function getValue(){
    console.log(5);
}

Func(1).getValue(); //为什么是1呢?

特定の実行分析

グローバル コードを実行し、グローバル実行コンテキストを作成すると、グローバル コンテキストが実行コンテキスト スタックにプッシュされます

ECStack = [ globalContext ];

グローバル コンテキストを初期化します

globalContext = {
    VO: {
        func: reference to function func(){},
        getValue: reference to function getValue(){}
    },
    Scope: [globalContext.VO],
    this: globalContext.VO //全局上下文
}

グローバル コンテキストを初期化すると 2 つの関数が同時に作成されるため、その親スコープ チェーンも内部プロパティ [[scope]]

func.[[scope]] = [
     globalContext.VO
];
getValue.[[scope]] = [
     globalContext.VO
];

に保存されます。時刻、コードの実行が開始されます。最後のステートメントが実行されると、最初に func 関数が実行され、ステップバイステップの func 関数実行コンテキストが作成されます。

  • Copy function [[scope ]] 属性を使用してスコープ チェーンを作成します

  • 引数を使用してアクティブ オブジェクトを作成します

  • ##アクティブ オブジェクトを初期化します

  • #アクティブなオブジェクトを checksfunccope スコープ チェーンの先頭にプッシュします。
  • これを作成します。簡単な分析: MemberExpression 値は func、func は関数オブジェクト、もちろん Reference、その基本値はEnvironmentRecord であるため、その this 値は ImplicitThisValue( ref) です。 、戻り値は常に未定義です。非厳密モードでは、その値は暗黙的にグローバル オブジェクトに変換されます。
  • funcContext = {
        AO: {
            arguments: { // 数组
                0: 1,
                length: 1
            }
        },
        Scope: [AO, globalContext.VO],
        this: undefined
    }
  • func の getValue についてはどうなるのでしょうか?という疑問を持つ人もいるかもしれません。変数宣言がないため、実際には属性割り当て操作であり、後で実行時に実行されます。

関数実行コンテキストを作成し、実行コンテキスト スタックにプッシュします。

    ECStack = [
        funcContext,
        globalContext
    ];

関数が実行を開始します。これが、

なぜ最終出力が 1

であるのかを知るための鍵です。最初の文の代入操作、次に実行コンテキストに沿って変数 getValue を見つける必要があります。次に funcContext のスコープを見てみましょう。まず funcContext.AO を見つけます。明らかに getValue 属性は存在しません。次にスコープ チェーンに沿って調べて見つけます。 globalContext.VO、getValueが見つかりました。このとき、グローバルスコープのgetValue属性が再割り当てされます。割り当てられるのは新しいバージョンの関数であり、関数スコープが再作成され、この親が割り当てられます新しい getValue 関数が再割り当てされます。レベル スコープ チェーンは内部プロパティ [[scope]]:

getValue .[[scope]] = [ funcContext.AO, globalContext.VO ];
に格納されます。次に、これを返し続け、funcContext のこれを見つけます。つまり、未定義の関数実行コンテキストを返します。 Pops

ECStack = [ globalContext ];

実行を続行

Func(1).getValue()

、前半は未定義を返します。このとき、システムは暗黙的にグローバル変数オブジェクトに変換し、そこから getValue 属性を見つけます。グローバル変数オブジェクト。この時点で、getValue はもう当時の少年ではないことがわかりました。新しい getValue の関数実行コンテキストがスタックにプッシュされました: <pre class="brush:js;toolbar:false;">getValueContext = { AO: { arguments: { // 数组 length: 0 } }, Scope: [ AO, funcContext.AO, globalContext.VO ], this: undefined } ECStack = [ getValueContext, globalContext ];</pre> 関数が実行を開始し、出力したいことがわかりました。

value

, スコープに沿って探します。getValueContext.AO にはそのような属性はありません。検索を続けて funcContext.AO を見つけます (Note!)。値が見つかった場合は、仮パラメータに入力すると、対応する値が出力されます。 関数の実行後、getValueContext と globalContext がスタックからポップされて次々に破棄され、コードが完成します。

概要

この映画では、単純だが単純ではない例を使用して、前の 4 つの記事を結び付け、JS コードが実行されるときの実行コンテキストを完全に分析します。この作業プロセスをより深く理解することができます。しかし、注意深い学生は、上記の例では、getValue 関数の実行中に、属性値を見つける (位置をマークする) ステップから、その時点で明らかに func 関数が実行されていることを発見したでしょうか。その実行コンテキストは解放されました。スタック、なぜまだその実行コンテキストから value 属性を見つけることができるのでしょうか?これは実際にはクロージャ生成の原理です。次の記事では、引き続きこの例を使用してクロージャ生成の原理を学習します。

[推奨学習:

JavaScript 上級チュートリアル

]

以上がJavascript の実行コンテキストについて説明する記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。