Maison >interface Web >js tutoriel >Démystifier les fermetures en JS

Démystifier les fermetures en JS

WBOY
WBOYoriginal
2024-09-01 21:13:321125parcourir

Demystifying Closures in JS

  • Doit être maîtrisé pour comprendre les détails complexes de la langue.
  • Pas créé comme nous créons un tableau ou une fonction.
  • Un fn renvoyant un autre fn qui est stocké dans la variable LHS.
const secureBooking = function(){
  let passengerCount = 0;
  return function(){
    passengerCount++;
    console.log(`${passengerCount} passengers`);
  }
}

const booker = secureBooking();

booker();
booker();
booker();
  • secureBooking fn est exécuté dans une portée globale.
  • Un nouveau contexte d'exécution sera créé sur le contexte d'exécution global.
  • Chaque contexte d'exécution (EC) possède son propre environnement de variables avec toutes ses variables. 'let passagerCount = 0' est défini à l'intérieur de cet EC. Il peut accéder à toutes les variables de sa portée parent.
  • Un nouveau fn est renvoyé et sera stocké dans booker.
  • Le Global EC contiendra également la variable booker.
  • Maintenant, secureBooking() sera supprimé d'EC et disparaîtra. L'environnement secureBooking EC n'est plus actif. Mais on accède toujours à la variable passagerCount qui a été définie au moment de la création de fn.
  • Néanmoins, le fn intérieur pourra accéder à la variable passagerCount définie à l'intérieur du fn extérieur. Cela se produit en raison de la fermeture.
  • La fermeture permet au fn de se souvenir des variables définies entourant le lieu de naissance du fn ou de son EC.
  • booker n'est pas un fn, situé à l'échelle mondiale.
  • Exécution en cours de booker(); pour la première fois créera un EC sur la pile d'appels, avec ses propres variables.
  • Un fn a accès à l'environnement variable du contexte d'exécution dans lequel le fn a été créé i. réservation sécurisée. Par conséquent, le booker aura accès aux variables définies dans l'environnement variable de secureBooking fn. Cette connexion du lieu de naissance de fn, c'est-à-dire de définition à son environnement variable environnant, est appelée fermeture même après que l'EC de secureBooking fn contenant le fn soit sorti de la pile d'appels.
  • Fermeture : Environnement variable attaché au fn, exactement tel qu'il était au moment et au lieu de création du fn.
  • La chaîne de portée est préservée grâce à la fermeture, même si l'EC a disparu, l'environnement variable continue de vivre d'une manière ou d'une autre dans le moteur. Par conséquent, nous disons que booker fn est fermé sur le parent fn, y compris les arguments parent fn que nous n'avons pas ici.
  • Grâce à la fermeture, un fn ne perd pas la connexion avec les variables définies autour de son lieu de naissance.
  • Si la variable n'est pas dans la portée actuelle, JS examine la fermeture avant même de rechercher la chaîne de portée. Supposons que s'il existe une variable globale, même dans ce cas, la variable définie dans sa fermeture est recherchée en premier.
  • La clôture a la priorité sur la chaîne de portée.
  • Après avoir exécuté booker() pour la première fois, la valeur de passagerCount est incrémentée, connectée à la console, puis le booker est retiré de la pile d'appels.
  • L'exécution passe à la ligne suivante, un nouveau EC est créé mais la variable de fermeture est toujours là. La valeur existante est incrémentée et l'EC apparaît.
  • Encore une fois, ce processus se répète pour la troisième fois.

RÉSUMÉ

  • Defn : Une fermeture est un environnement variable fermé de la CE dans lequel une fn a été créée, même après la disparition de cette CE.

  • De plus, une fermeture donne à un fn accès à toutes les variables de son fn parent, même après le retour de ce fn parent. Le fn conserve une référence à sa portée externe, ce qui préserve la chaîne de portée au fil du temps.

  • Une fermeture garantit que le fn ne perd pas la connexion avec les variables qui existaient au moment de la naissance du fn. C'est comme un sac à dos qu'un fn transporte partout où il va. Ce sac à dos contient toutes les variables qui étaient présentes dans l'environnement où le fn a été créé.

  • Nous n'avons pas besoin de créer des fermetures manuellement. De plus, nous ne pouvons même pas accéder explicitement aux variables fermées. Une fermeture n'est pas un objet JS tangible, c'est-à-dire que nous ne pouvons pas accéder à une fermeture et en extraire des variables. C'est une propriété interne d'un fn. Pour jeter un œil au sac à dos, "console.dir(booker);"
    [[Scope]] vous montrera le VE de cet appel fn.

  • [[]] signifie qu'il s'agit d'une propriété interne à laquelle nous ne pouvons pas accéder à partir de notre code.

  • Nous n'avons toujours pas besoin de renvoyer un fn à partir d'un autre fn pour créer une fermeture. Dans l'exemple ci-dessous, la variable « f » n'a même pas été définie à l'intérieur du fn, car elle a une portée globale. Il est également capable d'accéder à la variable 'a' même après que g() ait terminé son EC. 'a' est maintenant dans le sac à dos de 'f'.

let f;

const g = function(){
  const a = 23;
  f = function() {
    console.log(a*2); // 46
  };
};


const h = function(){
  const b = 777;
  f = function(){
    console.log(b*2); // 1554
  };
};

g();
f();
console.dir(f);

// f fn is reassigned using h fn. Hence, old closure value i.e 'a' will be replaced with new value 'b' which can be verified using console.dir().
h();
f();
console.dir(f);
  • setTimeout(callbackFnToBeCalled, Delay);
  • Les variables de fermeture ont une priorité plus élevée sur la chaîne de portée.
// Boarding Passengers using Closures
const boardPassengers = function(n, wait){
  const perGroup = n / 3;

  setTimeout(function(){
    console.log(`We are now boarding all ${n} passengers`);
    console.log(`There are 3 groups, each with ${perGroup} passengers`)
  }, wait*1000);

  console.log(`Will start boarding in ${wait} seconds`);
}

boardPassengers(180, 3);

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:[Forfait quotidien] msArticle suivant:[Forfait quotidien] ms