Avant-propos : Ceci est toujours un article d'introduction. Il existe plusieurs fonctionnalités de langage très importantes dans Javascript : les objets, l'héritage prototypique et les fermetures. Parmi eux, la fermeture est une nouvelle fonctionnalité du langage pour les programmeurs qui utilisent le langage statique traditionnel C/C. Cet article commencera par des exemples pour présenter les fonctionnalités du langage des fermetures Javascript et le combinera avec certaines spécifications du langage ECMAScript pour permettre aux lecteurs d'avoir une compréhension plus approfondie des fermetures.
Remarque : cet article est un article d'introduction. Les exemples de documents sont compilés à partir d'Internet. Si vous êtes un expert, vous êtes invités à fournir des suggestions techniques et des opinions sur l'article. Cet article traite de Javascript. Je ne veux pas faire de comparaison de langage. Si vous n'êtes naturellement pas à l'aise avec Javascript, veuillez faire un détour.
Qu'est-ce que la fermeture
Qu'est-ce qu'une fermeture ? Closure est Closure, qui est une nouvelle fonctionnalité que les langages statiques n'ont pas. Mais la fermeture n'est pas quelque chose de trop compliqué à comprendre. En bref, la fermeture c'est :
Une fermeture est une collection de variables locales d'une fonction, mais ces variables locales continueront d'exister après le retour de la fonction.
La fermeture signifie que la "pile" d'une fonction n'est pas libérée après le retour de la fonction. On peut aussi comprendre que ces piles de fonctions ne sont pas allouées sur la pile mais sur le tas
.
Lors de la définition d'une autre fonction au sein d'une fonction, une fermeture sera générée
La deuxième définition ci-dessus est la première explication supplémentaire, extrayant le sujet, le prédicat et l'objet de la première définition - la fermeture est l'ensemble des « variables locales » de la fonction. C'est juste que cette variable locale est accessible après le retour de la fonction. (Ce n'est pas une définition officielle, mais cette définition devrait vous être plus utile pour comprendre les fermetures)
En tant que variables locales, elles sont accessibles par le code dans la fonction. Ce n'est pas différent des langages statiques. La différence avec les fermetures est que les variables locales sont toujours accessibles par du code en dehors de la fonction après la fin de l'exécution de la fonction. Cela signifie que la fonction doit renvoyer une « référence » pointant vers la fermeture, ou attribuer cette « référence » à une variable externe pour garantir que les variables locales de la fermeture soient accessibles par du code externe. Bien entendu, l'entité contenant cette référence doit être un objet, car en Javascript, à l'exception des types de base, tout le reste est un objet. Malheureusement, ECMAScript ne fournit pas de membres ni de méthodes pertinents pour accéder aux variables locales dans les fermetures. Mais dans ECMAScript, la fonction interne (fonction interne) définie dans l'objet fonction peut accéder directement aux variables locales de la fonction externe. Grâce à ce mécanisme, nous pouvons compléter l'accès à la fermeture de la manière suivante.
Le résultat de l'exécution du code ci-dessus est : Hello Closure, car la fonction sayHello() peut toujours accéder au texte de la variable locale définie en son sein après l'exécution de la fonction de salutation.
D'accord, c'est l'effet légendaire des fermetures. Les fermetures ont une variété de scénarios et de modes d'application en Javascript, tels que Singleton, Power Constructor et d'autres modes Javascript qui sont indissociables de l'utilisation des fermetures.
Modèle de fermeture ECMAScript
Comment ECMAScript implémente-t-il les fermetures ? Ceux qui souhaitent en savoir plus peuvent obtenir la spécification ECMAScript pour la recherche. Je ne donnerai ici qu'une explication simple, et le contenu provient également d'Internet.
Lorsque la fonction du script ECMAscript est en cours d'exécution, chaque association de fonction possède une scène de contexte d'exécution (Contexte d'exécution). Cette scène de contexte d'exécution contient trois parties
.L'Environnement Lexical
L'Environnement Variable
cette reliure
Le troisième point, cette liaison, n’a rien à voir avec les fermetures et ne sera pas abordé dans cet article. L'environnement de grammaire est utilisé pour analyser les identifiants de variables utilisés lors de l'exécution de la fonction. Nous pouvons imaginer l'environnement de grammaire comme un objet contenant deux composants importants, l'enregistrement d'environnement (Enviroment Recode) et la référence externe (pointeur). L'enregistrement d'environnement contient des variables locales et des variables de paramètre déclarées à l'intérieur de la fonction, et les références externes pointent vers le scénario d'exécution contextuel de l'objet de fonction externe. La valeur de cette référence dans la scène de contexte global est NULL. Une telle structure de données forme une liste chaînée unidirectionnelle, chaque référence pointant vers la scène de contexte externe.
Par exemple, le modèle de fermeture de notre exemple ci-dessus devrait être comme ceci. La fonction sayHello est sur la couche inférieure, la couche supérieure est la fonction de salutation et la couche la plus externe est la scène globale. Comme indiqué ci-dessous : Ainsi, lorsque sayHello est appelé, sayHello trouvera la valeur du texte de la variable locale à travers la scène contextuelle, donc "Hello Closure" s'affiche dans la boîte de dialogue à l'écran. Les fonctions de l'environnement variable (The VariableEnvironment). et l'environnement grammatical sont fondamentalement similaires. Veuillez vous référer au document de spécification ECMAScript pour les différences spécifiques.
Exemple de séquence de fermetures
Auparavant, j'avais à peu près compris ce que sont les fermetures Javascript et comment les fermetures sont implémentées en Javascript. Ci-dessous, nous vous aiderons à comprendre plus en profondeur les fermetures à travers quelques exemples. Il y a 5 exemples ci-dessous. Les exemples proviennent de JavaScript Closures For Dummies (miroir). Exemple 1 : Les variables locales dans les fermetures sont des références plutôt que des copies
Le résultat de l'exécution devrait donc être 667 au lieu de 666.
Exemple 2 : Plusieurs fonctions lient la même fermeture car elles sont définies dans la même fonction.
Exemple 3 : Lors de l'attribution de fonctions dans une boucle, ces fonctions seront liées à la même fermeture
Le résultat de l'exécution de testList est que la fenêtre non définie item3 apparaît trois fois, car ces trois fonctions sont liées à la même fermeture, et la valeur de item est le dernier résultat calculé, mais quand je sors de la boucle, la valeur de i est 4, donc list Le résultat de [4] n'est pas défini.
Exemple 4 : Toutes les variables locales de la fonction externe sont dans la fermeture, même si cette variable est déclarée après la définition de la fonction interne.
Exemple 5 : Créer une nouvelle fermeture à chaque fois que la fonction est appelée
Singleton :