Maison > interface Web > js tutoriel > le corps du texte

Une introduction approfondie et simple au code et au texte des fermetures JavaScript (Closure)

黄舟
Libérer: 2017-03-03 15:37:16
original
1155 Les gens l'ont consulté

La fermeture (fermeture) est un seuil très important pour maîtriser Javascript du débutant à l'approfondissement. C'est une difficulté du langage Javascript et aussi sa caractéristique de nombreuses applications avancées. tout dépend de la fermeture. Notez mes notes d'étude ci-dessous~

Table des matières de la série

  • Explication détaillée de la fermeture de JavaScript (Closure)

  • Explication approfondie de JavaScript This

  • Une introduction approfondie à la chaîne de prototypes et à l'héritage de JavaScript


Fermetures - partout


Dans la programmation front-end, l'utilisation de fermetures est très courante Nous utilisons souvent des fermetures intentionnellement ou non, directement ou indirectement. Les fermetures peuvent rendre le transfert de données plus flexible (comme la gestion de certains événements de clic)

!function() {      
  var localData = "localData here";    
     document.addEventListener('click',    //处理点击事件时用到了外部局部变量,比如这里的localData       
        function(){              
           console.log(localData); 
    }); 
}();
Copier après la connexion

Un autre exemple est l'exemple suivant : (N'est-ce pas très convivial ~~)

!function() {      
  var localData = "localData here";      
  var url = "http://www.baidu.com/";      
  $.ajax({ 
     url : url,          
     success : function() {              
        // do sth...              
        console.log(localData); 
        } 
    }); 
}();
Copier après la connexion

Regardons un autre exemple~~Cette situation est ce que nous appelons habituellement la fermeture

function outer() {   
  var localVal = 30;    
  return function(){      
    return localVal;    
  } 
} 
var func = outer();  
func(); // 30
Copier après la connexion

Dans cet exemple, external() est appelé pour renvoyer la fonction anonyme function() Dans cette fonction anonyme, la fonction locale. La variable localVal de external() est accessible. Une fois l'appel external() terminé, lorsque func() est à nouveau appelée, la variable locale localVal de external() est toujours accessible

Le concept de fermeture.

la fermeture est différente de la fonction générale Une fonction qui permet à une fonction d'accéder toujours à des variables non locales lorsqu'elle est appelée en dehors de la portée lexicale immédiate. – Wikipédia

Une fermeture est une fonction qui peut lire les variables internes d'autres fonctions. – Ruan Yifeng

Étant donné que dans le langage Javascript, seules les sous-fonctions à l'intérieur de la fonction peuvent lire les variables locales, les fermetures peuvent être simplement comprises comme des « fonctions définies à l'intérieur d'une fonction ».

Donc, par essence, la fermeture est un pont reliant l'intérieur d'une fonction à l'extérieur de la fonction

Le but de la fermeture

Cette partie est reproduite à partir de ce blog post

Les fermetures peuvent être utilisées dans de nombreux endroits. Il a deux utilisations principales : l’une consiste à lire les variables à l’intérieur de la fonction, comme mentionné précédemment, et l’autre consiste à conserver les valeurs de ces variables en mémoire.

function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000
Copier après la connexion

Dans ce code, le résultat est en fait la fonction de fermeture f2. Il a été exécuté deux fois, la première fois, la valeur était de 999, la deuxième fois, la valeur était de 1 000. Cela prouve que la variable locale n dans la fonction f1 est toujours stockée en mémoire et n'est pas automatiquement effacée après l'appel de f1.

Pourquoi cela se produit-il ? La raison en est que f1 est la fonction parent de f2 et que f2 est affecté à une variable globale, ce qui fait que f2 est toujours en mémoire, et l'existence de f2 dépend de f1, donc f1 est toujours en mémoire et ne sera pas supprimé. une fois l'appel terminé, recyclé par le mécanisme de récupération de place (garbage collection).

Une autre chose à noter dans ce code est la ligne "nAdd=function(){n =1}". Tout d'abord, le mot-clé var n'est pas utilisé avant nAdd, donc nAdd est plutôt une variable globale. que les variables locales. Deuxièmement, la valeur de nAdd est une fonction anonyme, et la fonction anonyme elle-même est également une fermeture, donc nAdd est équivalent à un setter, qui peut opérer sur des variables locales à l'intérieur de la fonction en dehors de la fonction.


Fermeture-Encapsulation


(function() {   
   var _userId = 23492;   
   var _typeId = 'item';    
   var export = {}; 

   function converter(userId) {          
     return +userId; 
   } 
    export.getUserId = function() {         
       return converter(_userId);     
   } 
   export.getTypeId = function() {          
      return _typeId; 
   }         
   window.export = export;   //通过此方式输出
}());

  export.getUserId(); // 23492 
  export.getTypeId();  // item 
  export._userId;    // undefined  
  export._typeId;    // undefined       
  export.converter; // undefined
Copier après la connexion

Utiliser les caractéristiques des fermetures permet d'encapsuler certaines fonctions complexes Logiquement, dans cet exemple, les méthodes d'exportation (getUserId, getTypeId) sont appelées pour accéder indirectement aux variables privées de la fonction, mais _userId ne peut pas être obtenu en appelant directement export._userId. Il s'agit également d'une fonctionnalité couramment utilisée dans Node~


Erreurs courantes : fermeture de boucle


Dans le cas suivant, nous ajoutons 3 p, les valeurs sont aaa, bbb, ccc Ce que nous voulons réaliser, c'est cliquer sur aaa pour sortir 1, cliquer sur bbb pour sortir 2, cliquer sur ccc pour sortir 3

document.body.innerHTML = "<p id=p1>aaa</p>" + "<p id=p2>bbb</p><p id=p3>ccc</p>";  
for (var i = 1; i < 4; i++) {      
  document.getElementById(&#39;p&#39; + i).         
    addEventListener(&#39;click&#39;, function() {         
    alert(i); // all are 4! 
    });  
}
Copier après la connexion

<. 🎜>

Par conséquent, cliquer sur aaa, bbb ou ccc sont tous alert(4)~~

Le problème est que la valeur de

i est déjà 4 lorsque l'initialisation est terminé

Pour obtenir ce que nous voulons, cliquez sur aaa pour sortir 1, cliquez sur bbb pour sortir 2 et cliquez sur ccc pour sortir 3. Nous devons utiliser la technique de fermeture dans chaque boucle, enveloppez-la avec. une fonction anonyme qui est exécutée immédiatement. Si vous faites cela, la valeur de alert(i) sera à chaque fois extraite de i dans l'environnement de fermeture. Ce i produira 1, 2 et 3 de l'affectation i de chaque boucle <. 🎜>

document.body.innerHTML = "<p id=p1>aaa</p>" + "<p id=p2>bbb</p>" + "<p id=p3>ccc</p>";  
for (var i = 1; i < 4; i++) {
  !function(i){ //②再用这个参数i,到getElementById()中引用     
    document.getElementById(&#39;p&#39; + i).       
      addEventListener(&#39;click&#39;, function() {         
      alert(i); // 1,2,3
     });  
  }(i);  //①把遍历的1,2,3的值传到匿名函数里面
}
Copier après la connexion

Questions de réflexion

Si vous pouvez comprendre les résultats des deux morceaux de code suivants, vous devez comprendre le mécanisme de fonctionnement des fermetures. (Du professeur Ruan) Cette question est résumée en secondes ~~

Fragment de code 1

Fragment de code 2
var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());
Copier après la connexion

Ce qui précède est une analyse approfondie explication des images et des textes du code de fermeture JavaScript (Closure) sont présentés en détail. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !
var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());
Copier après la connexion


É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
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!