Pierre angulaire du front-end : le mécanisme d'exécution sous-jacent de la fonction

Prenez l'habitude d'écrire ensemble ! C'est le troisième jour de ma participation au "Nuggets Daily New Plan · April Update Challenge", [Cliquez pour voir les détails de l'événement]

création de fonction

La création d'une fonction ouvrira un espace dans la mémoire du tas Heap pour stocker la fonction. Les objets stockent des paires clé-valeur dans la mémoire de tas lorsque les objets sont créés, et les fonctions stockent trois parties dans la mémoire de tas :

  • Portée : [[portée]]
  • chaîne de fonctions
  • paire clé-valeur

Par exemple:

let a = [1,2];
function fn(b) {
	b[0] = 3;
  b = [4];
  b[1] = 5;
  console.log(b);
}
fn(a);
console.log(a);
复制代码

Bien que les objets contiennent des fonctions, il existe certaines différences dans le contenu de stockage entre la création de fonctions et la création d'autres objets :

  1. Allouez un espace (adresse hexadécimale) dans la mémoire du tas Heap.
  2. Contenu lié au magasin :
  • Stockage d'objets fonctionnels en trois parties
    1. Lors de la création d'une fonction, déclarez la portée [[portée]]. La fonction est créée dans ce contexte, et sa portée est qui.
    2. Stockez le code dans le corps de la fonction sous forme de chaîne.
    3. Traiter les fonctions comme des objets ordinaires pour stocker certaines paires clé-valeur
  • Le reste des objets stocke des paires clé-valeur
  1. Attribuez l'adresse mémoire créée à la variable ou à la fonction correspondante, qui est volatile pour les opérations ultérieures.

exécution de la fonction

1. Créer un contexte privé

Une fois la fonction exécutée, elle va créer un nouveau contexte privé "push into the stack". A chaque exécution de la fonction, un nouveau contexte privé est reformé, qui n'est pas forcément lié au contexte généré par l'exécution précédente. Le code de la fonction est dans le contexte privé exécuté dans le contexte. Lorsque la fonction est poussée dans la pile et exécutée, un objet variable privé AO (Active Object) sera créé, ce qui distingue VO ici. AO est une filiale de VO. Les variables créées dans le contexte privé sont stockées dans AO, telles que les paramètres, le levage de variables et les variables définies dans les fonctions.

2. Terminer l'opération d'initialisation

Une fois la fonction poussée dans la pile, certaines opérations d'initialisation seront effectuées avant le début de l'exécution officielle :

  • Initialiser la chaîne de portée << propre contexte privé, portée >>.
  • Initialisez ceci (les fonctions fléchées n'ont pas cette étape).
  • Initialiser les arguments (les fonctions fléchées n'ont pas cette étape).
  • affectation des paramètres.
  • Promotion variable.

3. Exécution du code

Exécutez les chaînes de code présentes dans la mémoire de tas dans l'ordre de haut en bas.

4. Faites éclater la pile pour libérer ou conserver

正常情况下,代码执行完成之后,私有上下文出栈被回收。但是遇到特殊情况,如果当前私有上下文执行完成之后中的某个东西被执行上下文以外的东西占用,则当前私有上下文就不会出栈释放,也就是形成了不被销毁的上下文,闭包。除了这上面两种情况还有一种情况是,上下文没有被占用,但是要紧接着被用一次,这样没有用完之前是不能释放的,用完在释放,这样就形成了一个临时不被释放 )。

函数每一次执行都是重新形成一个全新的私有上下文,意思就是如果一个函数被执行100次,也会对上面的步骤走100次,并且形成100个执行上下文。正常情况下,函数执行完就会出栈被释放,但是如果不能被释放(闭包),就会一直被保存在内存中,当达到栈内存的极限时就会出现爆栈。

还是用这段代码为例:

let a = [1,2];
function fn(b) {
	b[0] = 3;
  b = [4];
  b[1] = 5;
  console.log(b);
}
fn(a);
console.log(a);
复制代码

参考

Je suppose que tu aimes

Origine juejin.im/post/7083522201160253476
conseillé
Classement