En JavaScript, une fonction peut être considérée comme une sorte de donnée, qui peut être affectée à une variable et imbriquée dans une autre fonction.
var fun = function(){ console.log("平底斜"); }
function fun(){ var n=10; function son(){ n++; } son(); console.log(n); } fun(); //11 fun(); //11
Modifions légèrement le deuxième morceau de code ci-dessus :
var n=10; function fun(){ function son(){ n++; } son(); console.log(n); } fun(); //11 fun(); //12
Voyez-vous la différence ? Si vous ne comprenez pas les résultats de l'exécution du code, veuillez lire le billet de blog précédent pour une explication de la portée et de la chaîne de portée de JavaScript.
La variable n dans le code ci-dessus est une variable globale et peut être réaffectée à tout moment sans appeler la fonction fun. Afin d'éviter que la variable n soit polluée, ou de réduire la pollution des variables globales, nous devons mettre n dans la fonction en tant que variable locale.
function fun(){ var n=10; function son(){ n++; console.log(n); } son(); } fun(); //11 fun(); //11
Si nous pouvons appeler directement la fonction fils globalement, nous pouvons obtenir l'effet souhaité. La fonction fils existe désormais en variable locale. Pour y accéder globalement, il existe généralement deux méthodes :
La première consiste à attribuer des valeurs aux variables globales
var a; function fun(){ var n=10; a = function son(){ n++; console.log(n); } } fun(); //son() a(); //11 a(); //12
L'autre consiste à utiliser return pour renvoyer la valeur
function fun(){ var n=10; return function son(){ n++; console.log(n); } } var a=fun(); a(); //11 a(); //12
La fonction son() ci-dessus est une fermeture. Dans un sens, toutes les fonctions peuvent être considérées comme des fermetures. Une fermeture est une fonction qui peut accéder aux variables dans le cadre de la fonction externe.
var a; function fun(){ var n=10; a = function son(){ n++; console.log(n); } return a(); } fun(); //11 a(); //12 a(); //13 fun(); //11 a(); //12 a(); //13
C'est toujours le code ci-dessus. Modifions-le légèrement et regardons les résultats de l'exécution. En effet, la variable n est initialisée à chaque fois que la fonction fun() est exécutée.
L'avantage de la fermeture est de réduire les variables globales, d'éviter la pollution globale et de sauvegarder les variables locales en mémoire. Mais c'est à la fois un avantage et un inconvénient. S'il y a trop de fermetures dans un morceau de code, cela peut provoquer des fuites de mémoire. Étant donné que les variables locales de la fermeture ne seront pas recyclées par le mécanisme de garbage collection, elles doivent être manuellement affectées à null (en ce qui concerne les fuites de mémoire, un sujet séparé sera ouvert plus tard)