90 likes | 192 Views
Javascript les spécificités du langage - Partie 4 -. Les fonctions anonymes. En Javascript les fonctions (ou objets) sont des variables , on peut donc les passer en paramètre d’une autre fonction :. var maFonctionAppelee = function () { alert ("Je suis appelée"); }
E N D
Les fonctions anonymes En Javascript les fonctions (ou objets) sont des variables, on peut donc les passer en paramètre d’une autre fonction : var maFonctionAppelee = function() { alert("Je suis appelée"); } // Cette fonction appelle la fonction passée en paramètre var maFonctionAppelante = function(maFonction) { maFonction(); } // Appel de la fonction Appelante avec la fonction appelée en paramètre maFonctionAppelante(maFonctionAppelee);
Les fonctions anonymes De la même manière on peut directement passer la définition de la fonction en paramètre afin d’éviter de définir une fonction qui ne servira qu’une fois : // Appel de la fonction Appelante avec la fonction appelée en paramètre maFonctionAppelante(function() { alert("Je suis appelée"); });
Les fonctions anonymes On peut tout aussi bien appeler une fonction anonyme : Bien que dans ce cas ci, cela ne représente pas d’intérêt, cette particularité va nous permettre de mettre en places des closures. //Définition et appel de la fonction anonyme (function() { alert("Je suis appelée"); })();
Les closures (clotûres) Dans les exécutions non séquentielles, c'est-à-dire lorsqu’on utilise le gestionnaire d’événements ou les fonctions de délais (setTimeout et setInterval) il arrive souvent qu’on ait besoin d’utiliser des variables globales ou des paramètres d’entrée. Le principal problème c’est que le code appelé ne s’exécute pas séquentiellement avec le code appelant. Dans l’exemple de l’utilisation du setTimeout, le code placé après, en dehors de la fonction de callback du retardateur n’attend pas qu’il soit fini d’être exécuté pour poursuivre. Dans la plupart des cas, lorsque le retardateur déclenche sa fonction, le code global a fini son exécution, ce qui pose un vrai problème si on voulait utiliser les valeurs d’une variable au moment ou le retardateur est défini.
Les closures (clotûres) Prenons l’exemple suivant : var monTableau = ["element1", "element2", "element3", "element4", "element5"]; for(var index = 0; index < 3; index++) { window.setTimeout( // Fonction à lancer après le délai function() { alert(monTableau[i]) }, // Délai en millisecondes avant de lancer la fonction 1000 ); } Ici bien qu’on voudrait afficher pendant chaque seconde « element1 », « element2 » et « element3 », cependant, le script précédent va afficher 3 fois « element4 ». Effectivement la boucle est terminée depuis longtemps dés la première seconde, la variable « index » contient donc sa valeur à la sortie de la boucle, c'est-à-dire 3.
Les closures (clotûres) Pour éviter ça, nous allons devoir figer les valeurs des variables pour chaque appel du retardateur et pour ce faire nous allons utiliser une closure pour passer la valeur de l’index : var monTableau = ["element1", "element2", "element3", "element4", "element5"]; for(var index = 0; index < 3; index++) { window.setTimeout( // Closure ( function(copieIndex) { return function() { alert(monTableau[copieIndex]) } } ) ( index ), 1000); }
Les closures (clotûres) Dans ce cas la valeur de l’index est copiée à chaque passage de la boucle, la fonction anonyme est effectivement appelée à chaque fois et c’est son retour qui est déclenché sur le retardateur. Cela s’explique du fait les variables et les paramètres d’une fonction imbriquante sont toujours accessibles en l’état par la fonction imbriquée, même quand la fonction imbriquante a fini son exécution avant sa fonction imbriquée.
Les closures (clotûres) On utilise également ce système pour passer nos propres arguments dans un callback dont les arguments sont normalement définis par la fonction appelante : functionfaireSurClick(monArgument1, monArgument2) { var maVariable = 12; return function(event) { alert(monArgument1 + monArgument2 + maVariable); } } var element = document.getElementById('item'); // Au click on affichera 3 + 4 + 12, c'est à dire 19; element.onclick = faireSurClick (3,4); • Toute l’idée de la closure c’est d’appeler une fonction qui va stocker ses variables et ses paramètres en mémoire et retourner la vraie fonction de callback. Même si la fonction a terminé son exécution, ses variables et paramètres sont toujours accessibles par la fonction imbriquée.