Maison > interface Web > js tutoriel > Prenez une minute pour comprendre les fermetures JavaScript

Prenez une minute pour comprendre les fermetures JavaScript

黄舟
Libérer: 2017-02-23 13:33:50
original
962 Les gens l'ont consulté


Qu'est-ce qu'une fermeture ?

Regardons d'abord un morceau de code :

function a(){
    var n = 0;
    function inc() {
        n++;
        console.log(n);
    }
    inc();  
    inc(); 
}
a(); //控制台输出1,再输出2
Copier après la connexion

C'est simple. Regardons à nouveau un morceau de code :

function a(){
    var n = 0;
    this.inc = function () {
        n++; 
        console.log(n);
    };
}
var c = new a();
c.inc();    //控制台输出1
c.inc();    //控制台输出2
Copier après la connexion

C'est simple.

Qu'est-ce que la fermeture ? C'est la clôture !

Les fonctions qui ont accès à des variables dans la portée d'une autre fonction sont des fermetures. Ici, la fonction inc accède à la variable n dans le constructeur a, donc une fermeture est formée.

Regardons à nouveau un morceau de code :

function a(){
    var n = 0;
    function inc(){
       n++; 
       console.log(n);
    }
    return inc;
}
var c = a();
c();    //控制台输出1
c();    //控制台输出2
Copier après la connexion

Voyons comment il est exécuté :

var c = couter(), cette phrase couter() renvoie la fonction inc , alors cette phrase est équivalente à var c = inc;

 c(), cette phrase est équivalente à inc(); Notez que le nom de la fonction est juste un identifiant (pointeur vers la fonction), et () est la fonction d'exécution .

La traduction des trois phrases suivantes est : var c = inc; inc(); inc();, est-ce différent du premier morceau de code ? Non.

Qu'est-ce que la fermeture ? C'est la clôture !

Tous les tutoriels de manuels aiment utiliser le dernier paragraphe pour expliquer les fermetures, mais je pense que cela complique le problème. Ce qui est renvoyé ici est le nom de la fonction. Les étudiants qui n'ont pas vu la programmation C/C de Tan Haoqiang ne réalisent peut-être pas immédiatement la différence entre utiliser () et non. En d'autres termes, cette méthode d'écriture a son propre piège. Bien que cette façon d'écrire soit plus élégante, j'aime quand même simplifier le problème. Regardez le code 1 et le code 2. Avez-vous toujours du mal avec l'appel de fonction ?

Pourquoi tu l'écris comme ça ?

Nous savons que chaque fonction de js est une petite pièce sombre. Elle peut obtenir des informations externes, mais le monde extérieur ne peut pas voir directement le contenu à l'intérieur. Mettez la variable n dans une petite pièce noire. À l'exception de la fonction inc, il n'y a pas d'autre moyen d'accéder à la variable n. De plus, définir une variable n avec le même nom en dehors de la fonction a ne s'affecte pas. "encapsulation" .

La raison pour laquelle return est utilisé pour renvoyer l'identifiant de la fonction inc est que la fonction inc ne peut pas être appelée directement en dehors de la fonction a, donc return inc est liée à l'extérieur. Ceci dans le code 2 lie également inc à la. dehors. .

Pièges courants

Regardez ceci :

function createFunctions(){
    var result = new Array();
    for (var i=0; i < 10; i++){
        result[i] = function(){
            return i;
        };
    }
    return result;
}
var funcs = createFunctions();
for (var i=0; i < funcs.length; i++){
    console.log(funcs[i]());
}
Copier après la connexion

À première vue, je pensais qu'il produisait 0 ~ 9, mais ce n'est absolument pas le cas. Vous envisagez de produire 10 10 ?

Le piège ici est le suivant : la fonction avec () est la fonction d'exécution ! Une phrase simple comme var f = function() { alert('Hi'); ne fera pas apparaître de fenêtre. Ce n'est que lorsqu'elle est suivie de f(); La traduction du code ci-dessus est :

var result = new Array(), i;
result[0] = function(){ return i; }; //没执行函数,函数内部不变,不能将函数内的i替换!
result[1] = function(){ return i; }; //没执行函数,函数内部不变,不能将函数内的i替换!
...
result[9] = function(){ return i; }; //没执行函数,函数内部不变,不能将函数内的i替换!
i = 10;
funcs = result;
result = null;

console.log(i); // funcs[0]()就是执行 return i 语句,就是返回10
console.log(i); // funcs[1]()就是执行 return i 语句,就是返回10
...
console.log(i); // funcs[9]()就是执行 return i 语句,就是返回10
Copier après la connexion

Pourquoi seul le résultat est-il collecté mais pas moi ? Parce que je suis toujours référencé par fonction. Tout comme au restaurant, les assiettes sont toujours limitées, le serveur va donc patrouiller autour de la table pour récupérer les assiettes vides, mais comment ose-t-il récupérer les assiettes qui contiennent encore des légumes ? Bien entendu, si vous videz manuellement la vaisselle sur l'assiette (= nul), l'assiette sera emportée. C'est ce qu'on appelle le mécanisme de recyclage de la mémoire.

Quant à savoir comment la valeur de i peut encore être conservée, en fait, après avoir lu jusqu'au début de l'article, il ne devrait y avoir aucune raison de s'inquiéter. Ne devrait-il pas manquer un morceau de nourriture dans l’assiette après en avoir mangé un seul morceau ?

Pour résumer

Une fermeture est une fonction qui fait référence à une variable d'une autre fonction. Parce que la variable est référencée, elle ne sera pas recyclée, elle peut donc être utilisée pour encapsuler une variable privée. . C'est à la fois un avantage et un inconvénient. Les fermetures inutiles ne feront qu'augmenter la consommation de mémoire ! De plus, lorsque vous utilisez des fermetures, vous devez également faire attention à savoir si la valeur de la variable répond à vos exigences, car elle ressemble à une variable privée statique. Les fermetures sont généralement mélangées à beaucoup de choses. Ce n'est qu'en entrant en contact avec elles que vous pourrez approfondir votre compréhension. Ce n'est que le début pour parler des choses de base.

Ce qui précède vous prendra une minute pour comprendre le contenu des fermetures JavaScript. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (m.sbmmt.com) !


É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