Maison > interface Web > js tutoriel > Explication détaillée des fermetures dans les connaissances Javascript_Basic

Explication détaillée des fermetures dans les connaissances Javascript_Basic

WBOY
Libérer: 2016-05-16 16:24:21
original
934 Les gens l'ont consulté

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.

Copier le code Le code est le suivant :

fonction salutation (nom) {
var text = 'Bonjour' nom ; // variable locale
// A chaque appel, une fermeture est générée et l'objet fonction interne est renvoyé à l'appelant
Renvoyer function() { alert(text); }
>
var sayHello=greeting("Closure");
sayHello() // La variable locale text
est accessible via la fermeture

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

Copier le code Le code est le suivant :

fonction say667() {
// Variable locale qui se retrouve dans la fermeture
var num = 666;
var sayAlert = function() { alert(num); }
num ;
Retourner sayAlert ;
>

var sayAlert = say667();
sayAlert()

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.

Copier le code Le code est le suivant :

fonction setupSomeGlobals() {
// Variable locale qui se retrouve dans la fermeture
var num = 666;
// Stocke quelques références aux fonctions sous forme de variables globales
gNuméroAlerte = function() { alert(num);>
gIncreaseNumber = function() { num }
gSetNumber = function(x) { num = x }
>
setupSomeGlobals(); // Attribuer des valeurs à trois variables globales
gNuméroAlerte(); //666
gIncreaseNumber();
gNuméroAlerte(); // 667
gSetNumber(12);//
gAlertNumber();//12

Exemple 3 : Lors de l'attribution de fonctions dans une boucle, ces fonctions seront liées à la même fermeture

Copier le code Le code est le suivant :

fonction buildList(liste) {
var résultat = [];
pour (var i = 0; i < list.length; i ) {
        var item = 'item' list[i];
result.push( function() {alert(item ' ' list[i])} );
>
Résultat de retour ;
>
fonction testList() {
var fnlist = buildList([1,2,3]);
// utiliser j uniquement pour éviter toute confusion - pourrait utiliser i
pour (var j = 0; j < fnlist.length; j ) {
            fnlist[j]();
>
>

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.

Copier le code Le code est le suivant :

fonction sayAlice() {
var sayAlert = function() { alert(alice); // Variable locale qui se retrouve dans la fermeture
var alice = 'Bonjour Alice';
Retourner sayAlert ;
>
var bonjourAlice=sayAlice();
bonjourAlice();

Le résultat de l'exécution est une fenêtre pop-up de "Bonjour Alice". Même si la variable locale est déclarée après la fonction sayAlert, la variable locale reste accessible.

Exemple 5 : Créer une nouvelle fermeture à chaque fois que la fonction est appelée

Copier le code Le code est le suivant :
function newClosure(someNum, someRef) {
// Variables locales qui se retrouvent dans la fermeture
var num = unNum;
var anArray = [1,2,3];
var ref = someRef;
Fonction de retour (x) {
         num = x;
        anArray.push(num);
alert('num: 'num
          'nanArray ' anArray.toString()
          'nref.someVar ' ref.someVar);
>
>
Closure1=newClosure(40,{someVar:'closure 1'});
Closure2=newClosure(1000,{someVar:'closure 2'});

fermeture1(5); // num:45 anArray[1,2,3,45] ref:'someVar fermeture1'
fermeture2(-10);// num:990 anArray[1,2,3,990] ref:'someVar fermeture2'

Demande de clôture

Singleton :

Copier le code Le code est le suivant :
var singleton = fonction () {
var variable privée;
fonction fonction privée(x) {
           ...privateVariable...
>

Retour {
         firstMethod : fonction (a, b) {
                  ...privateVariable...
},
secondeMéthode : fonction (c) {
                  ...privateFunction()...
>
};
}();

Ce singleton est implémenté via des fermetures. L'encapsulation des membres privés et des méthodes est complétée par des fermetures. La fonction principale anonyme renvoie un objet. L'objet contient deux méthodes, la méthode 1 peut accéder aux variables privées et la méthode 2 peut accéder aux fonctions privées internes. Ce qui nécessite une attention particulière, c'est le '()' à la fin de la fonction principale anonyme. Sans ce '()', le singleton ne peut pas être généré. Parce que les fonctions anonymes ne peuvent renvoyer qu’un objet unique et ne peuvent pas être appelées depuis d’autres endroits. Voici comment utiliser les fermetures pour générer des singletons.


Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal