Créé le 07 Juillet 2008, par Anis Safine
Bonjour à tous ! 
Le grand jour est arrivé, nous allons enfin découvrir ensemble ces fameuses fonctions dont je vous parle tant depuis le début de ce cours !
Puissantes et indispensables... nous allons en manger des fonctions à partir de ce chapitre ! Et comme ce sera sans doute le chapitre le plus long et fastidieux de ce cours, je vous conseille de prendre quelques vitamines ! 
Remonter
1. Créer une fonction
A l'occasion de notre première instruction, je vous avais donné une rapide définition des fonctions en vous disant qu'"une fonction fait appel à un bloc d'instructions déjà tapé pour vous et sont là pour vous éviter d'avoir toujours tout à programmer vous même".
En fait, ce n'est pas compliqué, une fonction est comme une grande boîte dans laquelle on stocke une liste d'instructions. Et à chaque fois que l'on utilisera cette fonction, elle exécutera automatiquement cette liste d'instructions elle-même.
Comme je le disais, l'avantage principal quand on utilise une fonction, c'est que l'on est pas obligé de retaper à chaque fois un même bloc d'instructions. Mais ça rend aussi le code plus lisible.
Eh oui, on comprend facilement ce que la fonction "validerFormulaire" peut faire et même une personne ne connaissant que très peu le JavaScript comprendra ce que fait votre code, même s'il ne sait pas comment. Ce qui ne serait pas le cas si vous ne faisiez qu'aligner des instructions.
Bref, les fonctions c'est bien. La question maintenant, c'est comment créer ses propres fonctions ?
Pour y répondre, nous allons étudier les deux exemples suivants :
Code javascript
// On crée une première fonction
function afficher(tableau, indice) {
document.write(tableau[indice] + "<br/>");
}
// On crée une seconde fonction
function carre(nombre) {
return nombre * nombre;
}
Les paramètres
Pour créer une fonction, on commence donc par utiliser le mot-réservé "function" suivi de l'identifiant de la fonction à créer et puis les parenthèses dans lesquelles on liste les paramètres de la fonction.
Les para-quoi ? 
Oui, les paramètres. Si vous vous souvenez bien (et y a intérêt !
), dans les chapitres précédents, nous avons découvert des fonctions comme typeof() et document.write(). Je me suis contenté de vous donner des exemples d'utilisation de ces fonctions sans vous les expliquer.
A cela, il existe une raison simple : sans fonctions, les précédents chapitres auraient été très (trop) théoriques et je ne pouvais pas faire sans. D'un autre côté, il aurait été prématuré de vous donner ce chapitre sur les fonctions avant d'avoir vu les types de données, la manière de les manipuler etc.
J'ai donc essayé de trouver le juste milieu en vous présentant la syntaxe d'utilisation d'une fonction, tout en gardant suffisamment de mystère sur le pourquoi du comment, de manière à ne pas en perdre certains. 
Mais revenons à nos fonctions ! Leur point commun et leur force, c'est qu'elles peuvent recevoir des données pour les manipuler. Dans "typeof" par exemple, on envoie une variable à la fonction pour qu'elle nous renvoie le type de données qu'elle contient. Dans "document.write", on envoie une chaîne de caractères pour qu'elle l'affiche à l'écran. 
A chaque fois, les données que l'on envoie, on les met entre parenthèses, et c'est ça, les paramètres.
Donc quand on crée une fonction, le principe est simple : on liste entre les parenthèses les identifiants des variables qui seront crées pour contenir ces paramètres, en les séparant par des virgules.
Reprenons notre exemple. La première fonction que l'on crée, "afficher", compte 2 paramètres : "tableau" et "indice". Pour utiliser cette fonction, il faut donc lui envoyer deux données qui seront stockées respectivement dans "tableau" et "indice". 
Attention à bien se comprendre : ce que l'on liste entre les parenthèses lorsque l'on crée une fonction, ce sont les identifiants des variables qui seront créées et non pas les identifiants de variables déjà existantes !
Et à chaque fois que l'on utilisera notre fonction "afficher", cela créera automatiquement deux variables (en l'occurence "tableau" et "indice").
Gardez cette idée sous le coude, on va en reparler dans la dernière partie de ce chapitre ! 
Bien évidemment, vous pouvez donner le nom que vous voulez à vos paramètres ! "tableau" aurait pu s'appeler "choucroute" et "indice" aurait pu s'appeler "burger". Et enfin, vous n'êtes pas limités sur le nombre de paramètres : votre fonction peut ne rien recevoir, comme elle peut recevoir des centaines d'arguments ! 
Bien, nous en avons fini avec les paramètres. Nous pouvons passer à la suite ! 
Le corps de la fonction
Le corps d'une fonction, c'est ce qui suit la liste des paramètres que nous venons de voir, et il s'agit tout simplement de la liste des instructions qui composent notre fonction.
C'est précisément le bloc de code qui est lancé à chaque fois que l'on appelle la fonction !
Retournons une nouvelle fois examiner notre exemple. Le corps de la fonction "afficher" est :
Code javascript
document.write(tableau[indice] + "<br/>");
Comme vous pouvez le constater, on utilise la variable "tableau" et la variable "indice" qui sont les deux paramètres de la fonction "afficher". Bref, c'est tout bête. 
La seule chose vraiment très très importante à retenir, c'est que vous devez écrire le corps de votre fonction entre deux accolades, "{" et "}" ! Il s'agit d'un élément de syntaxe un peu particulier et qu'il faut vraiment retenir sinon comme toujours, votre code plantera minablement (eh oui, le monde de l'informatique se montre parfois cruel).
Nous avons donc fini avec la syntaxe de création d'une fonction ! Je vous propose un petit résumé pour que tout le monde ai les idées claires :
Code javascript
// Syntaxe générale de création d'une fonction
function identifiantDeLaFonction(parametre1, parametre2, ..., parametreX) {
instruction1;
instruction2;
...
instructionX;
}
Remonter
2. Utiliser une fonction
Nous savons maintenant créer une fonction et normalement, vous devriez savoir l'utiliser grâce aux chapitres précédents. Pour ceux qui n'auraient pas tout suivi, je reprends. 
Appeler une fonction
Une fois votre fonction créée, vous pouvez l'appeler autant de fois que vous le désirez ! Des centaines, des milliers, des millions de fois même ! (même si je ne pense pas que certains d'entre vous en arrive à de tels extrêmes...).
Pour se faire, il suffit d'utiliser l'identifiant de votre fonction suivi, entre parenthèses, des valeurs à donner aux paramètres, séparées par des virgules ! Comme ceci :
Code javascript
// Utilisation d'une fonction imaginaire "maFonction"
maFonction(parametre1, "bonjour", true, 150);
Vous pouvez passer en paramètre des valeurs directement tapées ou des valeurs contenues par des variables, et ce pour n'importe quel type de donnée (une chaîne de caractère, un booléen, un nombre...). 
Mais rien ne vaut un bon exemple concret et je crois que le mieux est encore de tester nos fonctions d'exemple vues plus haut (si ce n'est pas déjà fait pour certains !).
Testez donc le code suivant :
Code javascript
// On crée une première fonction
function afficher(tableau, indice) {
document.write(tableau[indice] + "<br/>");
}
// Exemples d'utilisation de cette fonction
var tableau1 = new Array(1, 50, 23, 10.34, 40);
afficher(tableau1, 2);
afficher(tableau1, 0);
afficher(tableau1, 4);
De rapides explications s'imposent, même si je pense que la plupart d'entre vous auront compris le système.
Dans un premier temps, on crée une fonction afficher tel que l'on a appris à le faire dans la partie précédente, qui accepte 2 paramètres : "tableau" et "indice". Comme ces identifiants l'indiquent, "tableau" doit recevoir un Array, et "indice" un nombre correspondant à un indice du tableau envoyé en paramètre. 
En effet, si on regarde le corps de cette fonction, on constate qu'elle a pour but d'afficher à l'écran le contenu de la case d'indice n°"indice" de "tableau" suivi d'un saut de ligne.
Ainsi, on crée un Array que l'on enregistre dans "tableau1", puis on demande à afficher le contenu de la case d'indice 2, 0 puis 4 de "tableau1", à l'aide de notre fonction toute neuve ! Comme vous pouvez le constater, ça éclaire le code, et c'est vachement plus pratique ! 
Voilà, appeler une fonction, c'est pas plus bête que ça, mais on a pas encore tout vu ! En avant !
Retour d'une fonction
Le titre est évocateur : "le retour d'une fonction". En fait, c'est assez simple : on a vu que des fonctions pouvaient recevoir des données que l'on appelait des paramètres.
Et bien les fonctions peuvent également renvoyer des données, que l'on appelle valeur de retour, ou tout simplement le retour de la fonction. La valeur retournée, ça peut être n'importe quoi, un booléen, un nombre, une chaîne de caractère, un tableau, un tableau de tableau bref...
Quel est l'intérêt ? Et bien parfois, on a pas forcément envie que notre fonction affiche quelque chose à l'écran mais qu'elle manipule des données et qu'elle nous donne le résultat de cette manipulation.
On peut se référer à notre deuxième fonction exemple, la fonction "carre" qui effectue le calcul du carré d'un nombre envoyé en paramètre. Eh bien dans ce cas là, on peut avoir simplement envie de récupérer la valeur de ce calcul (en général on utilise les fonctions pour des choses plus complexes bien évidemment).
Ainsi, dans le corps de la fonction, on met toutes les instructions que l'on veut pour manipuler les paramètres, et une fois qu'on a obtenu le résultat, on le retourne à l'aide du mot-réservé return qui a dû en intriguer plus d'un tout à l'heure ! 
Revoyons notre fonction "carre" :
Code javascript
function carre(nombre) {
return nombre * nombre;
}
C'est on ne peut plus clair, on utilise "return" suivi de la valeur à retourner. 
Vous allez me dire, "c'est bien beau de retourner une valeur, mais comment on la récupère ?".
Soit on l'enregistre dans une variable, soit on l'utilise directement dans une autre fonction, soit... on ne l'utilise pas du tout :
Code javascript
function carre(nombre) {
return nombre * nombre;
}
// On enregistre la valeur retournée avant de l'afficher
var resultat = carre(4);
document.write(resultat + "<br/>");
// Ou on l'utilise directement
document.write(carre(5) + "<br/>");
// Ou on ne l'utilise pas du tout... et là rien ne s'affiche
carre(6);
Vous pouvez tester ce bout de code et je pense que vous n'avez pas besoin d'explications supplémentaires. 
Il reste juste quelques petites précisions ! Sachez que dès que vous utilisez "return", la fonction s'arrête et ne va pas plus loin. En gros, si vous aviez encore d'autres instructions après votre "return", elles ne seront pas exécutées.
Pour illustrer cette idée, modifions un peu notre fonction "carre" :
Code javascript
function carre(nombre) {
// On prévient que le calcul va se faire
document.write('Calcul du carré de ' + nombre + '...');
// On retourne le résultat du calcul
return nombre * nombre;
// On prévient que le calcul a été effectué
document.write('<br/>Calcul effectué !');
}
// On enregistre la valeur retournée avant de l'afficher
var resultat = carre(4);
document.write(resultat + "<br/>");
// Ou on l'utilise directement
document.write(carre(5) + "<br/>");
// Ou on ne l'utilise pas du tout... et là rien ne s'affiche
carre(6);
Comme vous pourrez le constater après test, le premier message avertissant que le calcul va se faire est bien affiché, mais pas celui annonçant la fin du calcul car il se trouve après "return".
Si on y tenait vraiment, il faudrait déplacer cette instruction :
Code javascript
function carre(nombre) {
// On prévient que le calcul va se faire
document.write('Calcul du carré de ' + nombre + '...');
// On prévient que le calcul a été effectué
document.write('<br/>Calcul effectué !');
// On retourne le résultat du calcul
return nombre * nombre;
}
Voilà, ça n'a pas grand intérêt de construire sa fonction comme ça, mais au moins vous voyez bien comment cela marche (enfin j'espère !).
Allez dernière chose avant de terminer cette partie, à l'image de notre fonction d'exemple "afficher", sachez que vous n'êtes pas obligés de préciser une valeur de retour à vos fonctions. Retenez seulement que si vous ne précisez pas de valeur de retour, votre fonction retournera "undefined" par défaut. 
Voyez par vous-même :
Code javascript
function nulle() {
// Fonction qui ne contient rien
}
document.write(nulle());
Et c'est terminé pour l'utilisation des fonctions ! 
Remonter
3. Portée de variables
Nous voilà dans la dernière ligne droite de ce chapitre sur les fonctions : la portée de variables. Il s'agit d'une notion fondamentale et qui nécessite un peu de concentration car elle n'est pas forcément évidente ! Alors attention, suivez bien mon raisonnement ! 
En fait, vous le savez, on ne peut pas utiliser une variable tant qu'on ne l'a pas déclaré... c'est logique puisque cela signifierait qu'elle n'existe pas ! Le problème, c'est que lorsque l'on déclare une variable à l'intérieur d'une fonction, alors celle-ci n'existe pas en-dehors de cette fonction !
Ce que cela veut dire concrètement ? Observez cet exemple :
Code javascript
function exemple() {
var valeur = "Bonjour";
document.write(valeur);
}
document.write(valeur);
Si vous avez essayé de faire marcher ce code, vous constatez.... rien du tout ! Absolument rien, votre écran reste plus blanc que blanc... (OMO en resterait baba)... mince alors ! Cela signifie que la variable "valeur" n'existe pas !
Les plus malins d'entre vous vont alors s'exclamer : c'est normal ! c'est parce que l'on a jamais utilisé la fonction ! Si on l'utilise une première fois, le code contenu par la fonction s'exécute, la variable est créée et normalement, là, ça marche !
.
Malheureusement, le code suivant restera un échec critique pour vos neurones dépassés par la situation :
Code javascript
function exemple() {
var valeur = "Bonjour";
document.write(valeur);
}
exemple();
document.write(valeur);
Cette fois, "Bonjour" apparaît à l'écran mais cela est dû uniquement à l'appel de la fonction "exemple". Si "valeur" existait, alors un deuxième bonjour devrait s'afficher devant nos yeux ébahis !
Alors qu'en est-il de cette fichue variable ? Et bien nous sommes en plein dans ce que l'on appelle la portée des variables.
Finalement, le résultat de ces différents exemples n'est pas si étonnant puisque je vous avais annoncé d'entrée qu'une variable créée dans le corps d'une fonction n'existe pas en dehors de ce corps. La question reste pourquoi ?
En fait, lorsque l'on appelle une fonction, l'ordinateur va chercher le corps de cette fonction pour l'exécuter. Il va ainsi, si cela est demandé, créer des variables, les manipuler et une fois qu'il arrive à la fin du corps, il détruit automatiquement toutes les variables qu'il a créé depuis le début du corps !
On appelle ces variables, des variables locales à la fonction.
Vous voyez maintenant se dessiner le problème ? Cela explique la raison pour laquelle notre variable "valeur" n'existait pas ! 
Mais attention, ce n'est pas fini ! Il y a une nuance très importante à saisir, et les deux exemples à suivre vont nous permettre de cerner parfaitement l'idée de portée des variables :
Code javascript
var valeur = " test";
function exemple() {
var valeur = "Bonjour";
document.write(valeur);
}
exemple();
document.write(valeur);
Normalement, ça devrait vous piquer les yeux de voir une chose pareille : on déclare deux fois la même variable ! ... En fait non, car en fait une variable est distinguable par deux choses : son identifiant et son parent.
Ca y est, le mot est lâché... Qu'est-ce que le parent d'une variable ? Et bien il s'agit de la fonction ou le programme dans lequel elle a été créée. La première variable "valeur" (qui contient " test") a donc pour parent le programme JavaScript et la seconde a pour parent la fonction "exemple".
Du coup, les deux variables "valeur" sont des variables distinctes pour l'ordinateur car elles n'ont pas le même parent ! Et finalement, ce code est parfaitement valide.
A noter d'ailleurs que la première variable "valeur" est une variable dite globale. Nous allons voir pourquoi. 
Vous ne m'avez pas lâché ? Prenez le temps de remonter et de relire calmement tout ce que je viens de vous dire, parce qu'il est primordial de comprendre tout ça (et qu'une fois qu'on a compris, on trouve ça tout bête !).
Allez, vous êtes OK sur ce qu'on vient de dire ? Alors on en rajoute une couche avec le dernier exemple :
Code javascript
var valeur = "test";
function exemple() {
valeur = "Bonjour";
document.write(valeur);
}
exemple();
document.write(valeur);
Bon sang de bonsoir ! Cette fois-ci, on a deux "Bonjour" qui s'affichent à l'écran ! Qu'est-ce que cela signifie ?
Et bien réétudions calmement ce code. Contrairement à l'exemple précédent, cette fois, la fonction "exemple" n'a pas de variable locale : on ne fait que modifier la variable globale "valeur" déjà existante ! 
En fait, et c'est la conclusion à laquelle je voulais vous mener, c'est que si on ne peut pas utiliser une variable créée à l'intérieur d'une fonction depuis l'extérieur, en revanche, on peut utiliser depuis l'intérieur d'une fonction des variables qui ont été créées à l'extérieur. 
Cela justifie le fait d'appeler notre variable "valeur" une variable "globale" car elle est extérieure à toutes les fonctions du programme. Du coup, elle est accessible depuis n'importe quel endroit du programme !
Oui c'est un peu tordu la portée des variables, mais en fait, il faut comprendre comment l'ordinateur agit et fonctionne. Vous voyez bien qu'il y a une logique derrière toute cette histoire ! 
Bon, et dernière chose avant d'en finir ! Vous vous souvenez des paramètres ? (ceux qui répondent "non" on le droit de sortir) Je vous avais dit que c'était des variables qui étaient créées au début de la fonction pour contenir les données envoyées...
Et bien ce sont des variables locales à la fonction ! C'est à dire qu'elles sont automatiquement détruites à la fin du corps ! Gardez bien cela en tête ! Et voici un petit exemple :
Code javascript
function exemple(valeur) {
document.write(valeur);
}
exemple("Les fonctions, c'est super simple avec liketheweb.fr !");
document.write(valeur); // On constate que valeur n'existe pas : c'est une variable locale à "exemple"
Remonter
Conclusion
Ouf ! On s'en sortis indemnes ! Et on s'est désormais créer nos fonctions, les utiliser et surtout, surtout, surtout, on a compris comment elles fonctionnaient (subtil jeu de mot). 
Dans les deux prochains chapitres, on va apprendre à utiliser les conditions et les boucles. Ce seront les deux chapitres les plus rentables : ils sont simples et donnent des outils puissants et indispensables !