検索
ホームページウェブフロントエンドjsチュートリアルJSの実行コンテキストと実行スタックの詳細説明

JSの実行コンテキストと実行スタックの詳細説明

Nov 06, 2020 pm 05:47 PM
javascript実行コンテキスト

JSの実行コンテキストと実行スタックの詳細説明

JavaScript 開発者、または JavaScript 開発者になりたい場合は、JavaScript プログラムの内部実行メカニズムを理解する必要があります。実行コンテキストと実行スタックは、JavaScript の重要な概念の 1 つであり、JavaScript の難しさの 1 つです。実行コンテキストと実行スタックを理解することは、ホイスティング メカニズム、スコープ、クロージャなどの他の JavaScript の概念を理解するのにも役立ちます。この記事では、これらの概念をできるだけわかりやすく紹介します。

推奨チュートリアル: 「JavaScript ビデオ チュートリアル

1. 実行コンテキスト (Execution Context)

1. 実行コンテキストとは

要するに、実行コンテキストは、現在の JavaScript コードが解析および実行される環境の抽象的な概念です。JavaScript で実行されるコードはすべて、実行コンテキストで実行されます。

2. 実行コンテキストの種類

実行コンテキストには 3 つのタイプがあります:

  • グローバル実行コンテキスト: これはデフォルトで最も基本的な実行コンテキストです。どの関数にも含まれていないコードは、グローバル実行コンテキストにあります。 1. グローバル オブジェクトを作成しますブラウザでは、このグローバル オブジェクトはウィンドウ オブジェクトです。 2. this ポインタがこのグローバル オブジェクトを指すようにします。プログラム内に存在できるグローバル実行コンテキストは 1 つだけです。
  • 関数実行コンテキスト: 関数が呼び出されるたびに、その関数に対して新しい実行コンテキストが作成されます。各関数には独自の実行コンテキストがありますが、関数が呼び出されたときにのみ作成されます。関数実行コンテキストはプログラム内にいくつでも存在できます。新しい実行コンテキストが作成されるたびに、一連のステップが特定の順序で実行されます。これについては、この記事で後ほど説明します。
  • Eval 関数の実行コンテキスト: eval 関数で実行されるコードも独自の実行コンテキストを取得しますが、eval 関数は Javascript 開発者によって一般的に使用されないため、ここでは説明しません。

2. 実行コンテキストのライフ サイクル

実行コンテキストのライフ サイクルには 3 つの段階があります: 作成段階→実行段階→リサイクル段階、この記事創造段階に焦点を当てます。

1. 作成フェーズ

関数が呼び出されるとき、その内部コードが実行される前に、次の 3 つのことが行われます:

  • Create変数オブジェクト: まず関数のパラメータを初期化し、関数宣言と変数宣言を進めます。以下、これについて詳しく説明する。
  • スコープ チェーンの作成 (スコープ チェーン): 実行コンテキストの作成フェーズ中に、変数オブジェクトの後にスコープ チェーンが作成されます。スコープ チェーン自体には変数オブジェクトが含まれます。スコープ チェーンは変数を解決するために使用されます。変数を解決するよう求められると、JavaScript は常にコードのネストの最も内側のレベルから開始します。変数が最も内側のレベルで見つからない場合は、変数が見つかるまで 1 つ上のレベルの親スコープにジャンプします。
  • これがどこを指しているのかを判断します。これには、以下で詳しく説明する多くの状況が含まれます。

JS スクリプトを実行する前に、コードを解析する必要があります (つまり、JS はスクリプト言語です)解釈して実行する) を解析するときに、グローバル実行コンテキストが最初に作成され、実行されるコード内のすべての変数と関数の宣言が最初に取り出されます。変数は一時的に未定義に割り当てられ、関数は宣言されて使用できるようになります。このステップが完了すると、正式な実行プロセスを開始できます。

さらに、関数が実行される前に、関数実行コンテキストも作成されます。これはグローバル コンテキストに似ていますが、関数実行コンテキストにはこの引数と関数パラメーターが含まれます。

2. 実行フェーズ

実行変数の割り当て、コードの実行

3. リサイクル フェーズ

実行コンテキストはスタックからポップされ、実行コンテキストをリサイクルするための仮想マシン

3. 変数のプロモーションの詳細とこのポイント

##1. 変数宣言のプロモーション

##ほとんどのプログラミング言語は、最初に変数を宣言してから、同じ:

console.log(a); // undefined
var a = 10;

上記のコードは、通常、エラー

Uncaught ReferenceError: a が定義されていません## を報告する代わりに、

unknown を出力します。 #、これはステートメントの巻き上げが原因であり、次のコードと同等です:

var a; //声明 默认值是undefined “准备工作”
console.log(a);
a = 10; //赋值
2. 関数宣言のプロモーション

関数を作成するには 2 つの方法があることは誰もが知っています。関数宣言を通して

function foo(){}

もう 1 つは関数式を通してです var foo = function(){} では、関数の昇格における 2 つの違いは何ですか? ?

console.log(f1); // function f1(){}
function f1() {} // 函数声明
console.log(f2); // undefined
var f2 = function() {}; // 函数表达式
次に例を使用してこの問題を説明します。
function test() {
    foo(); // Uncaught TypeError "foo is not a function"
    bar(); // "this will run!"
    var foo = function() {
        // function expression assigned to local variable 'foo'
        alert("this won't run!");
    };
    function bar() {
        // function declaration, given the name 'bar'
        alert("this will run!");
    }
}
test();

上の例では、foo() が呼び出されたときにエラーが報告されますが、bar は通常どおり呼び出すことができます。

変数と関数が上昇すると前に述べましたが、関数式

var foo = function(){}

に遭遇すると、

var foo は最初に At the まで上昇します。ただし、この時点の foo の値は未定義であるため、foo() を実行するとエラーが報告されます。

而对于函数bar(), 则是提升了整个函数,所以bar()才能够顺利执行。

有个细节必须注意:当遇到函数和变量同名且都会被提升的情况,函数声明优先级比较高,因此变量声明会被函数声明所覆盖,但是可以重新赋值。

alert(a); //输出:function a(){ alert('我是函数') }
function a() {
    alert("我是函数");
} //
var a = "我是变量";
alert(a); //输出:'我是变量'

function 声明的优先级比 var 声明高,也就意味着当两个同名变量同时被 function 和 var 声明时,function 声明会覆盖 var 声明

这代码等效于:

function a() {
    alert("我是函数");
}
var a; //hoisting
alert(a); //输出:function a(){ alert('我是函数') }
a = "我是变量"; //赋值
alert(a); //输出:'我是变量'

最后我们看个复杂点的例子:

function test(arg) {
    // 1. 形参 arg 是 "hi"
    // 2. 因为函数声明比变量声明优先级高,所以此时 arg 是 function
    console.log(arg);
    var arg = "hello"; // 3.var arg 变量声明被忽略, arg = 'hello'被执行
    function arg() {
        console.log("hello world");
    }
    console.log(arg);
}
test("hi");
/* 输出:
function arg(){
    console.log('hello world') 
    }
hello 
*/

这是因为当函数执行的时候,首先会形成一个新的私有的作用域,然后依次按照如下的步骤执行:

  • 如果有形参,先给形参赋值
  • 进行私有作用域中的预解释,函数声明优先级比变量声明高,最后后者会被前者所覆盖,但是可以重新赋值
  • 私有作用域中的代码从上到下执行

3. 确定 this 的指向

先搞明白一个很重要的概念 —— this 的值是在执行的时候才能确认,定义的时候不能确认! 为什么呢 —— 因为 this 是执行上下文环境的一部分,而执行上下文需要在代码执行之前确定,而不是定义的时候。看如下例子:

// 情况1
function foo() {
  console.log(this.a) //1
}
var a = 1
foo()

// 情况2
function fn(){
  console.log(this);
}
var obj={fn:fn};
obj.fn(); //this->obj

// 情况3
function CreateJsPerson(name,age){
//this是当前类的一个实例p1
this.name=name; //=>p1.name=name
this.age=age; //=>p1.age=age
}
var p1=new CreateJsPerson("尹华芝",48);

// 情况4
function add(c, d){
  return this.a + this.b + c + d;
}
var o = {a:1, b:3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

// 情况5
<button id="btn1">箭头函数this</button>
<script type="text/javascript">
    let btn1 = document.getElementById(&#39;btn1&#39;);
    let obj = {
        name: &#39;kobe&#39;,
        age: 39,
        getName: function () {
            btn1.onclick = () => {
                console.log(this);//obj
            };
        }
    };
    obj.getName();
</script>

接下来我们逐一解释上面几种情况

  • 对于直接调用 foo 来说,不管 foo 函数被放在了什么地方,this 一定是 window
  • 对于 obj.foo() 来说,我们只需要记住,谁调用了函数,谁就是 this,所以在这个场景下 foo 函数中的 this 就是 obj 对象
  • 在构造函数模式中,类中(函数体中)出现的 this.xxx=xxx 中的 this 是当前类的一个实例
  • call、apply 和 bind:this 是第一个参数
  • 箭头函数 this 指向:箭头函数没有自己的 this,看其外层的是否有函数,如果有,外层函数的 this 就是内部箭头函数的 this,如果没有,则 this 是 window。

JSの実行コンテキストと実行スタックの詳細説明

四、执行上下文栈(Execution Context Stack)

函数多了,就有多个函数执行上下文,每次调用函数创建一个新的执行上下文,那如何管理创建的那么多执行上下文呢?

JavaScript 引擎创建了执行上下文栈来管理执行上下文。可以把执行上下文栈认为是一个存储函数调用的栈结构,遵循先进后出的原则

JSの実行コンテキストと実行スタックの詳細説明

从上面的流程图,我们需要记住几个关键点:

  • JavaScript 执行在单线程上,所有的代码都是排队执行。
  • 一开始浏览器执行全局的代码时,首先创建全局的执行上下文,压入执行栈的顶部。
  • 每当进入一个函数的执行就会创建函数的执行上下文,并且把它压入执行栈的顶部。当前函数执行完成后,当前函数的执行上下文出栈,并等待垃圾回收。
  • 浏览器的 JS 执行引擎总是访问栈顶的执行上下文。
  • 全局上下文只有唯一的一个,它在浏览器关闭时出栈。

我们再来看个例子:

var color = "blue";
function changeColor() {
    var anotherColor = "red";
    function swapColors() {
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
    }
    swapColors();
}
changeColor();

上述代码运行按照如下步骤:

  • 当上述代码在浏览器中加载时,JavaScript 引擎会创建一个全局执行上下文并且将它推入当前的执行栈
  • 调用 changeColor 函数时,此时 changeColor 函数内部代码还未执行,js 执行引擎立即创建一个 changeColor 的执行上下文(简称 EC),然后把这执行上下文压入到执行栈(简称 ECStack)中。
  • 执行 changeColor 函数过程中,调用 swapColors 函数,同样地,swapColors 函数执行之前也创建了一个 swapColors 的执行上下文,并压入到执行栈中。
  • swapColors 函数执行完成,swapColors 函数的执行上下文出栈,并且被销毁。
  • changeColor 函数执行完成,changeColor 函数的执行上下文出栈,并且被销毁。

JSの実行コンテキストと実行スタックの詳細説明

更多编程相关知识,请访问:编程学习网站!!

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

声明
この記事は博客园で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
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は柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソースPython vs. JavaScript:コミュニティ、ライブラリ、リソースApr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

DVWA

DVWA

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