検索
ホームページウェブフロントエンドjsチュートリアルjsの実行コンテキストと変数オブジェクトの分析

この記事の内容は、js の実行コンテキストと変数オブジェクトの分析に関するものです。必要な方は参考にしていただければ幸いです。

実行コンテキスト

JavaScript コードの実行プロセスには、コンパイルと実行の 2 つの段階が含まれます。コンパイルでは、字句解析を通じて抽象構文ツリーを構築し、JavaScript コードがコンパイルされる段階でそれを機械が認識する命令にコンパイルします。スコープのルールが決定されている; コードの実行段階で、または関数が呼び出されると、実行環境とも呼ばれる実行コンテキスト (実行コンテキスト) が作成されます

ECMA-262 には次の定義があります

コントローラー ECMA スクリプトの実行可能コードを入力すると、コントローラーは実行環境に入ります。現在アクティブな複数の実行環境が論理的にスタック構造を形成します。論理スタックの最上位の実行環境は、現在実行中の実行環境と呼ばれます。コントローラーが、現在実行中の実行環境に依存する実行可能コードから、その実行環境に依存しない実行可能コードに移行するたびに、新しい実行環境が作成されます。新しく作成された実行環境はスタックにプッシュされ、現在実行中の実行環境になります。

これも抽象的な概念ですが、1 つの JavaScript コード内で複数の実行コンテキストが作成され、変数または関数が定義されます。仕様や関連ドキュメントを読んで、実行コンテキスト (略して EC) には主に 3 つのポイントが含まれていることがわかりました。これらは、疑似コードで次のように表現されています。

EC = {
    this: // 绑定this指向为当前执行上下文, 如果函数属于全局函数,则this指向window
    scopeChain: [] // 创建当前执行环境的作用域链,
    VO: {} // 当前环境的变量对象(Variable Object),每个环境都有一个与之关联的变量对象
}

次のコード部分を見てください:

var a = 1;
function foo() {
    var b = 2;
    function bar() {
        console.log(b)
    }
    bar()
    console.log(a);
}

foo()
  • 1. これを実行します。このコードでは、最初にグローバル コンテキスト globalEC が作成され、実行コンテキスト スタックにプッシュされます。

  • 3. bar() が呼び出されると、bar のコンテキスト barEC が作成され、実行コンテキスト スタックにプッシュされます

  • 4. bar 関数が実行されると、 barEC は実行コンテキスト スタックからポップアップします

  • 5. foo 関数が実行されると、fooEC が実行コンテキスト スタックからポップアップします

  • 6. ブラウザ ウィンドウが閉じられた後、グローバル コンテキスト globleEC

  • 概要: スタックの一番下は常にグローバル コンテキストであり、スタックの一番上は現在実行中のコンテキストです。ブラウザが閉じている場合にのみ、グローバル コンテキストがポップアップされます。実行コンテキスト スタック

変数オブジェクト:

各実行環境には、抽象概念である関連する変数オブジェクトがあり、環境内で定義されたすべての変数と関数がこのオブジェクトに格納されます。私たちが作成するコードはこのオブジェクトにアクセスできませんが、単一のパーサーはデータを処理するときにバックグラウンドでオブジェクトを使用します。 ブラウザが初めて js スクリプト プログラムをロードすると、デフォルトでグローバル実行環境に入り、グローバル環境変数オブジェクトは window になり、コード内でアクセスできます。

環境が関数の場合、このアクティブ オブジェクトを現在のコンテキストの変数オブジェクトとして使用します (VO = AO)。このとき、コードから変数オブジェクトにアクセスすることはできません。以下では主にアクティブ オブジェクトについて説明します。

アクティベーションオブジェクト

1. アクティビティオブジェクト(以下AOと略します)を初期化します関数が呼び出されると、現在のコンテキストのアクティブオブジェクトが即座に作成され、アクティブオブジェクトは変数オブジェクトとして使用されます。引数属性 初期化、値は引数オブジェクトです (渡される実際のパラメータのセットは仮パラメータとは何の関係もありません。仮パラメータはローカル環境のローカル変数として定義されます)

AO = {
  arguments: <argo>
};</argo>

arguments オブジェクトには次の属性があります:

length:
    実際に渡されるパラメータの数;
  • callee:
  • は、呼び出される関数である現在の関数への参照を参照します;
  • 'クラスインデックス':
  • 文字列型の整数。値は引数オブジェクトのオブジェクトの下にあります。添字値、引数オブジェクトは配列と区別する必要がありますが、配列と同じ長さ属性を持ちます。サブスクリプトを介してアクセスできます
  • function show (a, b, c) {
        // 通过Object.prototype.toString.call()精准判断类型, 证明arguments不同于数组类型
        var arr = [1, 2, 3];
        console.log(Object.prototype.toString.call(arr)); // [object Array]
    
        console.log(Object.prototype.toString.call(arguments)); // [object Arguments]
    
        console.log(arguments.length) // 2  传递进来实参的个数
    
        console.log(arguments.callee === show) // true 就是被调用的函数show自身
    
        //参数共享
    
        console.log(a === arguments[0]) // true
    
        a = 15;
    
        console.log(arguments[0]) // 15
    
        arguments[0] = 25;
    
        console.log(a)  // 25;
    
        但是,对于没有传进来的参数c, 和arguments的第三个索引是不共享的
    
        c = 25;
    
        console.log(arguments[2]) // undefined
    
        argument[2] = 35;
    
        console.log(c) // 25
    
    }
    
    show(10, 20);
    次に、これが重要なポイントです。実行環境のコードは処理のために 2 つの段階に分かれています:

実行環境に入る

  1. 実行するコード関数

  2. 2. 実行環境に入る

  3. 関数が呼び出されたら、実行環境 (コンテキスト) に入り、すぐにアクティブなオブジェクトを作成し、引数属性を通じて初期化します。同時に、すべての仮パラメータが、実行環境内のすべての関数宣言とすべての変数宣言がスキャンされ、アクティブ オブジェクト (AO) に追加され、その値が決定されて、コードの実行が開始されます。

実行環境に入る段階:

すべての仮パラメータ宣言:

実パラメータが渡された場合、その値はアクティブなオブジェクト属性として作成されます。パラメータが渡されない場合、値は未定義です

すべての関数宣言:

変数の場合、値はアクティブなオブジェクトのプロパティとして作成されます。オブジェクトには同じ名前のプロパティがすでに存在するため、完全に置き換えられます。

すべての変数宣言:
所有变量名称作为活动对象的属性被创建, 值为undefined,但是和函数声明不同的是, 如果变量名称跟已经存在的属性(形式参数和函数)相同、则不会覆盖
function foo(a, b) {
    var c = 10;
    function d() {
        console.log('d');
    }
    var e = function () {
        console.log('e');
    };
    (function f() {})
    if (true) {
        var g = 20;
    } else {
        var h = 30;
    }
}

foo(10);

此时在进入foo函数执行上下文时,foo的活动对象fooAO为:

fooAO = {
    arguments: {
        0: 10,
        length: 1
    },
    a: 10,
    b: undefined,
    c: fundefined,
    d: <d>  //指向d函数的指针,
    e: undefined,
    g: undefined,
    h: undefined  // 虽然else中的代码永远不会执行,但是h仍然是活动对象中的属性
}</d>

这个例子做如下几点说明:

  • 1.关于函数,只会创建函数声明作为活动对象的属性, 而f函数作为函数表达式并不会出现在活动对象(AO)中

  • 2.e虽然值是一个函数, 但是作为变量属性被活动对象创建

3、代码执行阶段

在进入执行上下文阶段,活动对象拥有了属性,但是很多属性值为undefined, 到代码执行阶段就开始为这些属性赋值了

还是上面的代码例子, 此时活动对象如下:

fooAO = {
    arguments: {
        0: 10,
        length: 1
    },
    a: 10,
    b: undefined,
    c: 10, // 赋值为undefined
    d: <d>  //指向d函数的指针,
    e: <d>  // 指向e函数的指针
    g: 20,
    h: undefined  // 声明h变量,但是没有赋值
}</d></d>

变量对象包括:{ arguments对象+函数形参+内部变量+函数声明(但不包含表达式) }

这时这个活动对象, 即作为当前执行环境的变量对象会被推到此执行环境作用域链的最前端(作用域链本篇不做介绍,会在下一篇文章中单独讲解作用域和作用域链), 假定执行环境为一个对象,则整个执行环境可以访问到的属性如下:

伪代码如下:

fooExecutionContext = {
    scopeChain: [], //fooAO +所有父执行环境的活动对象,
    fooAO: {
        arguments: {
            0: 10,
            length: 1
        },
        a: 10,
        b: undefined,
        c: 10, // 赋值为undefined
        d: <d>  //指向d函数的指针,
        e: <d>  // 指向e函数的指针
        g: 20,
        h: undefined
    },
    this: 当前执行环境的上下文指针
}</d></d>

补充:

下面的例子为了说明一下变量声明的顺序及变量同名不会影响函数声明

console.log(foo); //  foo的函数体
var foo = 10;
console.log(foo) // 10
function foo() {};
foo = 20;
console.log(foo); // 20

在代码执行之前, 就会读取函数声明,变量声明的顺序在函数声明和形参声明之后, 整个流程如下:

进入执行环境阶段:

1. var VO = {}
2. VO[foo] = 'foo函数指针'
3. 扫描到var foo = 10,

 // 但是foo做为function已经声明,所以变量声明不会影响同名的函数声明,如果代码中没有foo函数声明的话,则foo为undefined

代码执行阶段:

1. VO[foo] = 10;
2. VO[foo] = 20;

解析代码完成。

相关推荐:

js对象是什么?js对象的介绍(附代码)

Js中前端模块化的详细分析及其区别对比

js中字符方法以及字符串操作方法的总结(附代码)

以上がjsの実行コンテキストと変数オブジェクトの分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
CおよびJavaScript:接続が説明しましたCおよびJavaScript:接続が説明しましたApr 23, 2025 am 12:07 AM

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Python vs. JavaScript:ユースケースとアプリケーションと比較されますPython vs. JavaScript:ユースケースとアプリケーションと比較されますApr 21, 2025 am 12:01 AM

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

JavaScript通訳者とコンパイラにおけるC/Cの役割JavaScript通訳者とコンパイラにおけるC/Cの役割Apr 20, 2025 am 12:01 AM

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

JavaScript in Action:実際の例とプロジェクトJavaScript in Action:実際の例とプロジェクトApr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptとWeb:コア機能とユースケースJavaScriptとWeb:コア機能とユースケースApr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンの理解:実装の詳細JavaScriptエンジンの理解:実装の詳細Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。