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

jsの実行コンテキストと変数オブジェクトの分析

Aug 14, 2018 am 10:02 AM
javascript

この記事の内容は、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>
};
ログイン後にコピー

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 reference>  //指向d函数的指针,
    e: undefined,
    g: undefined,
    h: undefined  // 虽然else中的代码永远不会执行,但是h仍然是活动对象中的属性
}
ログイン後にコピー

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

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

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

3、代码执行阶段

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

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

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

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

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

伪代码如下:

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

补充:

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

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 までご連絡ください。

ホット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

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScriptでinsertBeforeを使用する方法 JavaScriptでinsertBeforeを使用する方法 Nov 24, 2023 am 11:56 AM

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

JavaScript と WebSocket: 効率的なリアルタイム画像処理システムの構築 JavaScript と WebSocket: 効率的なリアルタイム画像処理システムの構築 Dec 17, 2023 am 08:41 AM

JavaScript は Web 開発で広く使用されているプログラミング言語であり、WebSocket はリアルタイム通信に使用されるネットワーク プロトコルです。 2 つの強力な機能を組み合わせることで、効率的なリアルタイム画像処理システムを構築できます。この記事では、JavaScript と WebSocket を使用してこのシステムを実装する方法と、具体的なコード例を紹介します。まず、リアルタイム画像処理システムの要件と目標を明確にする必要があります。リアルタイムの画像データを収集できるカメラ デバイスがあるとします。

See all articles