Maison  >  Article  >  interface Web  >  Série avancée JavaScript : fermetures et références

Série avancée JavaScript : fermetures et références

黄舟
黄舟original
2017-02-08 09:46:081056parcourir
  • Variables privées simulées

  • Pourquoi les variables privées ne sont pas accessibles en externe

  • Fermetures dans les boucles

  • Éviter les erreurs de référence

La fermeture est une fonctionnalité très importante de JavaScript, ce qui signifie que la portée actuelle peut toujours accéder à la variable de portée externe. Étant donné que les fonctions sont les seules structures en JavaScript à avoir leur propre portée, la création de fermetures repose sur des fonctions.

Simuler des variables privées

function Counter(start) {
    var count = start;
    return {
        increment: function() {
            count++;
        },

        get: function() {
            return count;
        }
    }
}

var foo = Counter(4);
foo.increment();
foo.get(); // 5

Ici, la fonction Counter renvoie deux fermetures, la fonction incrément et la fonction get. Les deux fonctions conservent une référence au compteur de portée externe, afin qu'elles puissent toujours accéder au nombre de variables défini dans cette portée.

Pourquoi les variables privées ne sont-elles pas accessibles en externe ?

Étant donné que la portée ne peut pas être référencée ou attribuée en JavaScript, il n'y a aucun moyen d'accéder à la variable de comptage en externe. Le seul moyen est de passer par ces deux fermetures.

var foo = new Counter(4);
foo.hack = function() {
    count = 1337;
};

Le code ci-dessus ne modifiera pas la valeur de la variable count définie dans la portée Counter, car foo.hack n'est pas défini dans cette portée. Cela créera ou écrasera le nombre de variables globales.

Fermetures dans les boucles

Une erreur courante se produit lors de l'utilisation de fermetures dans des boucles, en supposant que nous devons appeler le numéro de séquence de la boucle dans chaque boucle

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);  
    }, 1000);
}

Le Le code ci-dessus n'affichera pas les nombres 0 à 9, mais affichera le nombre 10 dix fois.

Lorsque console.log est appelé, la fonction anonyme conserve une référence à la variable externe i A ce moment, la boucle for est terminée et la valeur de i a été modifiée à 10.

Afin d'obtenir le résultat souhaité, vous devez créer une copie de la variable i dans chaque boucle.


Éviter les erreurs de référence

Afin d'obtenir correctement le numéro de séquence de la boucle, il est préférable d'utiliser un wrapper anonyme (Note du traducteur : en fait, il est ce que nous appelons habituellement la fonction anonyme d'auto-exécution).

for(var i = 0; i < 10; i++) {
    (function(e) {
        setTimeout(function() {
            console.log(e);  
        }, 1000);
    })(i);
}

La fonction anonyme externe sera exécutée immédiatement et prendra i comme paramètre. À ce moment, la variable e dans la fonction aura une copie de i.

Lorsque la fonction anonyme passée à setTimeout est exécutée, elle a une référence à e, et cette valeur ne sera pas modifiée par la boucle.

Il existe une autre façon d'accomplir le même travail, et c'est de renvoyer une fonction à partir d'un wrapper anonyme. Cela a le même effet que le code ci-dessus.

for(var i = 0; i < 10; i++) {
    setTimeout((function(e) {
        return function() {
            console.log(e);
        }
    })(i), 1000)
}

Ce qui précède est le contenu de la série JavaScript avancée - fermetures et références. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !


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