Nous rencontrons souvent des questions sur l'amélioration des variables d'évaluation dans les premières étapes de l'apprentissage de JS ou lors des entretiens. Par exemple, commençons par un plus simple.
console.log(a); // 这里会打印出什么?
var a = 20;
Copier après la connexion
Ignorant cet exemple pour le moment, introduisons d'abord le concept le plus basique mais aussi le plus important en JavaScript, le contexte d'exécution (Execution Context).
Chaque fois que le contrôleur passe en code exécutable, il entre dans un contexte d'exécution. Le contexte d'exécution peut être compris comme l'environnement d'exécution du code actuel, qui forme une portée. L'environnement d'exécution en JavaScript comprend grossièrement trois situations.
1. Environnement global : le code JavaScript entrera d'abord dans cet environnement lors de l'exécution
2. Environnement de fonction : lorsqu'une fonction est appelée et exécutée, elle entrera dans la fonction actuelle pour exécuter le code <. 🎜>
3.eval
Par conséquent, dans un programme JavaScript, plusieurs contextes d'exécution doivent être générés Comme mentionné dans mon article précédent, le moteur JavaScript les traitera de manière stack. Le bas de la pile est toujours le contexte global et le haut de la pile est le contexte en cours d'exécution.
Lorsque le code rencontre les trois situations ci-dessus lors de l'exécution, un contexte d'exécution sera généré et placé sur la pile. Une fois le contexte en haut de la pile exécuté, il sortira automatiquement de la pile. Afin de mieux comprendre ce processus, nous allons vous le montrer à partir des exemples et schémas suivants.
var color = 'blue';
function changeColor() {
var anotherColor = 'red';
function swapColors() {
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
}
swapColors();
}
changeColor();
Copier après la connexion
Nous utilisons ECStock pour représenter la pile qui gère les groupes de contexte d'exécution. Nous pouvons facilement savoir que la première étape consiste à pousser le contexte global sur la pile.
Une fois le contexte global placé sur la pile, le code exécutable qu'il contient commence à s'exécuter jusqu'à ce qu'il rencontre changeColor(). Cette phrase active la fonction changeColor pour créer la sienne. contexte d'exécution, donc la première La deuxième étape consiste à pousser le contexte d'exécution de changeColor sur la pile.
Une fois le contexte de changeColor placé sur la pile, le contrôleur commence à exécuter le code exécutable qu'il contient et active un contexte d'exécution après avoir rencontré swapColors(). Par conséquent, la troisième étape consiste à pousser le contexte d’exécution de swapColors sur la pile.
Dans le code exécutable de swapColors, il n'y a aucune autre situation qui peut générer un contexte d'exécution, donc ce code est exécuté avec succès et le contexte de swapColors est extrait de la pile .
Après l'apparition du contexte d'exécution de swapColors, le code exécutable de changeColor continue d'être exécuté et aucun autre contexte d'exécution n'est rencontré après une exécution réussie. De cette façon, il n'y a qu'un contexte global dans ECStack.
Le contexte global apparaît après la fermeture de la fenêtre du navigateur.
Remarque : dans une fonction, rencontrer return peut directement mettre fin à l'exécution du code exécutable, de sorte que le contexte actuel sera extrait directement de la pile.
Après avoir compris ce processus en détail, nous pouvons résumer quelques conclusions sur le contexte d'exécution.
1. Thread unique
2. Exécution synchrone, seul le contexte en haut de la pile est en cours d'exécution, les autres contextes doivent attendre
3. contexte global, il Pop la pile lorsque le navigateur est fermé
4 Il n'y a pas de limite au nombre de contextes d'exécution d'une fonction
5. être un nouveau contexte d'exécution pour sa création, même s'il s'agit d'une fonction appelée en soi.
Afin de consolider la compréhension du contexte d'exécution, dessinons l'évolution d'un exemple. Il s'agit d'un exemple simple de clôture.
function f1(){
var n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
Copier après la connexion
Parce que la fonction f2 dans f1 n'est pas appelée pour exécution dans le code exécutable de f1, donc lorsque f1 est exécuté, f2 ne créera pas de nouveau contexte, et il ne sera pas créé tant que le résultat n'est pas obtenu. exécuté. J’en ai un nouveau. Le processus d’évolution spécifique est le suivant.