Comment démarrer rapidement avec VUE3.0 : Entrez dans l'apprentissage
Recommandations associées : Tutoriels JavaScript
On entend probablement souvent « environnement d'exécution », « portée », « prototype (chaîne) », « contexte d'exécution », etc. Que décrivent-ils ?
Nous savons que js est un langage faiblement typé et que le type de variable n'est déterminé qu'au moment de l'exécution. Lorsque le moteur js exécute le code js, il effectuera également une analyse lexicale , une analyse syntaxique , une analyse sémantique et d'autres traitements de haut en bas, et générera un AST (arbre de syntaxe abstrait) une fois l'analyse du code terminée, et enfin générera du code machine. que le CPU peut exécuter sur la base de l'AST et exécuter.
De plus, le moteur JS effectuera également d'autres traitements lors de l'exécution du code. Par exemple, il y a deux étapes dans la V8 :
Cela conduit à deux concepts : "Contexte d'exécution" et "chaîne de portée".
D'après ce qui précède, nous pouvons savoir : lorsque le code js exécute un morceau de code exécutable, le contexte d'exécution correspondant sera créé.
Tout d'abord, il existe un concept correspondant au code exécutable en js : "environnement d'exécution" - environnement global, environnement de fonction et eval
.
Deuxièmement, pour chaque contexte d'exécution, il existe trois attributs importants :
Examinons deux morceaux de code :
var scope="global scope" function checkscope(){. var scope="portée locale"; fonction f(){ portée de retour ; } return f();}checkscope();
var scope="portée globale";function checkscope(){ var scope="portée locale"; fonction f(){ portée de retour ; } return f;}checkscope()();
Que vont-ils imprimer ?
Pourquoi? La réponse est que leurs piles de contextes d’exécution sont différentes !
Qu'est-ce que la « pile de contexte d'exécution » ?
Lors de l'exécution d'un code exécutable, des préparations seront effectuées à l'avance. Les « préparations » sont ici professionnellement appelées « contexte d'exécution ». Mais avec l’augmentation du code exécutable comme les fonctions, comment gérer autant de contextes d’exécution ? Le moteur JS a donc créé le concept de pile de contexte d'exécution.
On peut tout à fait utiliser un tableau pour simuler son comportement (il y a toujours un contexte d'exécution global globalContext en bas de la pile).
On définit un EStack, d'abord
EStack=[globalContext]
puis simule le premier morceau de code :
EStack. push(<checkscope> functionContext); EStack.push(<f> functionContext);EStack.pop();EStack.pop();
Et le deuxième morceau de code ressemble à ceci :
EStack.push(<checkscope> functionContext); EStack.pop();EStack.push (<f> functionContext);EStack.pop();
La raison est que vous devrez peut-être d'abord étudier le concept de « fermeture » !
Au fait, comment réaliser une « sauvegarde des données à long terme » dans la « modularisation frontale » ?
cache ? Non. Fermeture!
Tout d'abord, la portée fait référence à la zone du programme où les variables sont définies. La portée spécifie comment trouver la variable, qui détermine les droits d'accès du code en cours d'exécution à la variable.
Il existe deux types de portée : la portée statique et la portée dynamique .
La portée statique utilisée par JS est également appelée « portée lexicale ». La portée d'une fonction est déterminée lorsque la fonction est définie.
D'après ce qui précède, les variables à portée lexicale auront une certaine portée pendant le processus de compilation. Cette portée est le « contexte d’exécution actuel ». Après ES5, nous utilisons « environnement lexical » au lieu de portée pour décrire le contexte d'exécution. L'environnement lexical se compose de deux membres :
Regardons toujours un exemple :
var value=1 ;fonction foo(){ console.log(value);}barre de fonctions(){ valeur var=2 ; foo();}bar();
En regardant la définition ci-dessus, que faut-il imprimer ?
Analysons le processus d'exécution :
Exécutez la fonction foo(), recherchez d'abord dans la fonction foo pour voir s'il existe une valeur de variable locale. Sinon, recherchez le code sur la couche supérieure en fonction de la position lorsqu'il a été défini, c'est-à-dire valeur = 1. Le résultat sera donc imprimé comme 1.
Bien sûr, ce n'est pas si simple et peut être résumé. Vous pouvez l'analyser du point de vue du contexte d'exécution.
Nous avons parlé ci-dessus des deux composantes de l'environnement lexical (portée). En combinaison avec le contexte d'exécution, il n'est pas difficile de constater que grâce à la référence à l'environnement lexical externe, la portée peut être étendue le long de la pile couche par couche, établissant une structure de chaîne s'étendant vers l'extérieur de l'environnement actuel.
Regardons un autre exemple :
function foo(){ console.dir(bar); var a = 1 ; barre de fonctions(){ une = 2 ; }}console.dir(foo);foo();
À partir de la portée statique, la fonction globale foo crée un attribut [[scope]]
de son propre objet
foo
[[scope]]=[globalContext];
( ), il entrera également successivement la période de définition et la période d'exécution de la fonction foo.
Pendant la période de définition de la fonction foo, la [[scope]] de la barre de fonctions inclurala
[[scope]]
globale intégrée et la portée intégrée de foo
bar[[scope]]=[fooContext,globalContext];
ce point : "JS passera. Les références d'environnement lexical externe sont utilisées pour créer une chaîne de portée d'objets variables, garantissant ainsi un accès ordonné aux variables et fonctions auxquelles l'environnement d'exécution a accès. "
Revenons à la question dans le contexte d'exécution, Nous l'avons dit plus tôt. Quelle est la différence entre eux ? Voyons pourquoi ils affichent « portée locale » de la même manière : c'est toujours la même phrase « JS utilise la portée lexicale, et la portée de la fonction dépend de l'emplacement où la fonction est créée. » - Exécution de la fonction JS Une chaîne de portée est utilisée, qui est créée lorsque la fonction est définie. La fonction imbriquée f() est définie dans cette chaîne de portée, et la portée de la variable doit faire référence à des variables locales, peu importe quand et où f() est exécutée, cette liaison est toujours valide lorsque f() est exécutée.
Lorsqu'une variable est introuvable dans son propre enregistrement d'environnement lexical, elle peut être recherchée dans la couche externe en fonction de la référence de l'environnement lexical externe jusqu'à ce que la référence de l'environnement lexical externe dans l'environnement lexical le plus externe soit null
.
La "recherche basée sur une chaîne de prototypes dans les objets" est similaire à celle-ci :
__proto__
is null). La différence est également évidente : la chaîne de prototypes est un lien qui établit l'héritage d'objet via l'attribut prototype ; tandis que la chaîne de portée fait référence à la fermeture qui permet aux fonctions internes d'accéder aux fonctions externes. Que ce soit directement ou indirectement, toutes les chaînes de portée des fonctions sont finalement liées au contexte global.
Recommandations associées : Tutoriel d'apprentissage JavaScript
Ce qui précède est une compréhension approfondie de la façon dont le moteur JavaScript exécute le code JS. Pour plus d'informations, veuillez prêter attention aux autres articles connexes sur le site Web PHP chinois !