


Explication détaillée du contexte d'exécution et de la pile d'exécution dans JS
Si vous êtes un développeur JavaScript, ou souhaitez devenir développeur JavaScript, alors vous devez connaître le mécanisme d'exécution interne d'un programme JavaScript. Le contexte d'exécution et la pile d'exécution sont l'un des concepts clés de JavaScript et l'une des difficultés de JavaScript. Comprendre le contexte d'exécution et la pile d'exécution permet également de comprendre d'autres concepts JavaScript tels que le mécanisme de levage, la portée et la fermeture. Cet article présente ces concepts de la manière la plus simple à comprendre possible.
Tutoriel recommandé : "Tutoriel vidéo JavaScript"
1. Contexte d'exécution (Contexte d'exécution)
1. 🎜>En bref, le contexte d'exécution est le concept abstrait de l'environnement dans lequel le code JavaScript actuel est analysé et exécuté. Tout code exécuté en JavaScript s'exécute dans le contexte d'exécution
Types de contexte d'exécution
.Il existe trois types de contexte d'exécution :
Contexte d'exécution global : Il s'agit du contexte d'exécution par défaut et le plus basique. Le code qui n'est dans aucune fonction se trouve dans le contexte d'exécution global. Cela fait deux choses : 1. Créer un objet global dans le navigateur, cet objet global est l'objet fenêtre. 2. Pointez le pointeur this vers cet objet global. Un seul contexte d'exécution global peut exister dans un programme.- Contexte d'exécution de fonction : Chaque fois qu'une fonction est appelée, un nouveau contexte d'exécution est créé pour la fonction. Chaque fonction possède son propre contexte d'exécution, mais celui-ci n'est créé que lorsque la fonction est appelée. N'importe quel nombre de contextes d'exécution de fonctions peut exister dans un programme. Chaque fois qu'un nouveau contexte d'exécution est créé, il effectue une série d'étapes dans un ordre spécifique, qui seront abordées plus loin dans cet article.
- Contexte d'exécution de la fonction Eval : Le code exécuté dans la fonction eval obtient également son propre contexte d'exécution, mais comme la fonction eval n'est pas couramment utilisée par les développeurs Javascript, elle ne sera pas abordée ici.
- 2. Le cycle de vie du contexte d'exécution
Le cycle de vie du contexte d'exécution comprend trois phases :
Phase de création → Phase d'exécution → Phase de recyclage, qui l'article se concentre sur la phase de création. 1. Phase de création
Lorsqu'une fonction est appelée, mais avant que l'un de ses codes internes ne soit exécuté, les trois choses suivantes seront effectuées :
Créer un objet variable : initialisez d'abord les paramètres de la fonction et promouvez la déclaration de fonction et la déclaration de variable. Ceci sera expliqué en détail ci-dessous.- Créer une chaîne de portée : lors de la phase de création du contexte d'exécution, la chaîne de portée est créée après l'objet variable. La chaîne de portée elle-même contient des objets variables. La chaîne de portée est utilisée pour résoudre les variables. Lorsqu'on lui demande d'analyser une variable, JavaScript démarre toujours au niveau le plus interne de l'imbrication du code. Si la variable n'est pas trouvée au niveau le plus interne, il passera au niveau supérieur de la portée parent jusqu'à ce qu'il trouve la variable.
- Déterminez où cela pointe : y compris de nombreuses situations, qui seront expliquées en détail ci-dessous
- Avant qu'un script JS ne soit exécuté, le code doit être analysé (JS est donc un langage de script qui interprète et exécute) , lors de l'analyse, un contexte d'exécution global sera créé en premier et toutes les déclarations de variables et de fonctions dans le code qui sera exécuté seront supprimées en premier. Les variables sont temporairement affectées à undefined et les fonctions sont déclarées et prêtes à l'emploi. Une fois cette étape terminée, le processus d’exécution formel peut alors commencer.
De plus, avant qu'une fonction ne soit exécutée, un contexte d'exécution de fonction sera également créé, qui est similaire au contexte global, mais le contexte d'exécution de fonction aura ces arguments et paramètres de fonction.
2. Phase d'exécution
Exécuter l'affectation des variables et l'exécution du code
3. Phase de recyclage
Le contexte d'exécution sort de la pile et attend le virtuel. machine pour recycler le contexte d'exécution
3. Détails de la promotion des variables et ce pointage
1 Promotion de la déclaration des variables
La plupart des langages de programmation déclarent d'abord les variables, puis les utilisent. , mais en JS, les choses sont un peu différentes. Idem :
console.log(a); // undefined var a = 10;
Le code ci-dessus génère normalement
au lieu de signaler une erreur Cela est dû au levage de déclaration, ce qui équivaut à ce qui suit. code : undefined
var a; //声明 默认值是undefined “准备工作” console.log(a); a = 10; //赋值
Uncaught ReferenceError: a is not defined
2. Levage de la déclaration de fonctionNous savons tous qu'il existe deux façons de créer une fonction, l'une par déclaration de fonction
et l'autre par fonction expression function foo(){}
, alors ces deux méthodes sont différentes dans la promotion de fonction Quelle est la différence ?
console.log(f1); // function f1(){} function f1() {} // 函数声明 console.log(f2); // undefined var f2 = function() {}; // 函数表达式
var foo = function(){}
Ensuite, nous utilisons un exemple pour illustrer ce problème : 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();
Dans l'exemple ci-dessus, une erreur est signalée lorsque foo() est appelé, mais bar peut être appelé normalement.
Nous avons déjà dit que les variables et les fonctions augmenteront. Lorsqu'on rencontrera une expression de fonction
, montera d'abord au sommet du corps de la fonction. Cependant, la valeur de foo à ce moment n'est pas définie. , donc exécution var foo = function(){}
Signaler une erreur. var 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('btn1'); let obj = { name: 'kobe', 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。
四、执行上下文栈(Execution Context Stack)
函数多了,就有多个函数执行上下文,每次调用函数创建一个新的执行上下文,那如何管理创建的那么多执行上下文呢?
JavaScript 引擎创建了执行上下文栈来管理执行上下文。可以把执行上下文栈认为是一个存储函数调用的栈结构,遵循先进后出的原则。
从上面的流程图,我们需要记住几个关键点:
- 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 函数的执行上下文出栈,并且被销毁。
更多编程相关知识,请访问:编程学习网站!!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment utiliser WebSocket et JavaScript pour mettre en œuvre un système de reconnaissance vocale en ligne Introduction : Avec le développement continu de la technologie, la technologie de reconnaissance vocale est devenue une partie importante du domaine de l'intelligence artificielle. Le système de reconnaissance vocale en ligne basé sur WebSocket et JavaScript présente les caractéristiques d'une faible latence, d'un temps réel et d'une multiplateforme, et est devenu une solution largement utilisée. Cet article explique comment utiliser WebSocket et JavaScript pour implémenter un système de reconnaissance vocale en ligne.

WebSocket et JavaScript : technologies clés pour réaliser des systèmes de surveillance en temps réel Introduction : Avec le développement rapide de la technologie Internet, les systèmes de surveillance en temps réel ont été largement utilisés dans divers domaines. L'une des technologies clés pour réaliser une surveillance en temps réel est la combinaison de WebSocket et de JavaScript. Cet article présentera l'application de WebSocket et JavaScript dans les systèmes de surveillance en temps réel, donnera des exemples de code et expliquera leurs principes de mise en œuvre en détail. 1. Technologie WebSocket

Introduction à l'utilisation de JavaScript et de WebSocket pour mettre en œuvre un système de commande en ligne en temps réel : avec la popularité d'Internet et les progrès de la technologie, de plus en plus de restaurants ont commencé à proposer des services de commande en ligne. Afin de mettre en œuvre un système de commande en ligne en temps réel, nous pouvons utiliser les technologies JavaScript et WebSocket. WebSocket est un protocole de communication full-duplex basé sur le protocole TCP, qui peut réaliser une communication bidirectionnelle en temps réel entre le client et le serveur. Dans le système de commande en ligne en temps réel, lorsque l'utilisateur sélectionne des plats et passe une commande

Comment utiliser WebSocket et JavaScript pour mettre en œuvre un système de réservation en ligne. À l'ère numérique d'aujourd'hui, de plus en plus d'entreprises et de services doivent fournir des fonctions de réservation en ligne. Il est crucial de mettre en place un système de réservation en ligne efficace et en temps réel. Cet article explique comment utiliser WebSocket et JavaScript pour implémenter un système de réservation en ligne et fournit des exemples de code spécifiques. 1. Qu'est-ce que WebSocket ? WebSocket est une méthode full-duplex sur une seule connexion TCP.

JavaScript et WebSocket : Construire un système efficace de prévisions météorologiques en temps réel Introduction : Aujourd'hui, la précision des prévisions météorologiques revêt une grande importance pour la vie quotidienne et la prise de décision. À mesure que la technologie évolue, nous pouvons fournir des prévisions météorologiques plus précises et plus fiables en obtenant des données météorologiques en temps réel. Dans cet article, nous apprendrons comment utiliser la technologie JavaScript et WebSocket pour créer un système efficace de prévisions météorologiques en temps réel. Cet article démontrera le processus de mise en œuvre à travers des exemples de code spécifiques. Nous

Tutoriel JavaScript : Comment obtenir le code d'état HTTP, des exemples de code spécifiques sont requis Préface : Dans le développement Web, l'interaction des données avec le serveur est souvent impliquée. Lors de la communication avec le serveur, nous devons souvent obtenir le code d'état HTTP renvoyé pour déterminer si l'opération a réussi et effectuer le traitement correspondant en fonction de différents codes d'état. Cet article vous apprendra comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournira quelques exemples de codes pratiques. Utilisation de XMLHttpRequest

Utilisation : En JavaScript, la méthode insertBefore() est utilisée pour insérer un nouveau nœud dans l'arborescence DOM. Cette méthode nécessite deux paramètres : le nouveau nœud à insérer et le nœud de référence (c'est-à-dire le nœud où le nouveau nœud sera inséré).

JavaScript est un langage de programmation largement utilisé dans le développement Web, tandis que WebSocket est un protocole réseau utilisé pour la communication en temps réel. En combinant les puissantes fonctions des deux, nous pouvons créer un système efficace de traitement d’images en temps réel. Cet article présentera comment implémenter ce système à l'aide de JavaScript et WebSocket, et fournira des exemples de code spécifiques. Tout d’abord, nous devons clarifier les exigences et les objectifs du système de traitement d’images en temps réel. Supposons que nous disposions d'un appareil photo capable de collecter des données d'image en temps réel.
