Faire le quiz close

Les fonctions en JavaScript

#1 Prérequis open

Pour faire ce tutoriel, vous devez déjà avoir des notions sur les fonctions. Si ce n'est pas le cas, je vous conseille de faire le tutoriel sur la fonction dans la playlist "Débuter la programmation par JavaScript".

Ci-dessous, je vais faire le bilan de ce que nous avons déjà vu dans la playlist :

  1. Nous avons répondu à la question : Pourquoi utiliser une fonction ? Nous avons vu qu'une fonction pouvait être vue comme une boîte dans laquelle on sous-traitait un calcul. On peut préciser, qu'il peut y avoir dans cette boîte un traitement complet, voir une fonctionnalité complète d'un logiciel.
    Synoptique d'une fonction
  2. On a vu qu'il fallait faire une déclaration de fonction, et une seule, pour ensuite l'appeler autant de fois qu'on le voulait.
  3. On a vu qu'au moment de la déclaration, il fallait spécifier la liste des paramètres de déclaration et qu'au moment de l'appel, il fallait passer une liste de paramètres d'appel. Le tableau ci-dessous résume les autres terminologies utilisées.
    Paramètres utilisés à la déclaration Paramètres utilisés à l'appel
    Paramètres formels Paramètres effectifs
    Paramètres Arguments
    Paramètres de déclaration Paramètres d'appel
  4. On a appelé plusieurs fois la fonction en utilisant comme paramètres d'appel des valeurs.
  5. Dans la déclaration, on a vu que notre fonction utilisait une variable locale dont la portée se limitait à la fonction. De même, les paramètres de déclaration sont, eux aussi, locaux à la fonction.
  6. On a utilisé l'instruction return pour retourner la valeur d'un calcul.

Ci-dessous, une portion de code utilisé dans le tutoriel sur la fonction qui est dans la playlist "Débuter la programmation par JavaScript".

#2 Qu'est-ce qu'on peut mettre comme paramètres d'appel ? open

Pour ce tuto, vous devez créer avec Sublime un nouveau fichier sur le bureau. Vous l'appelez fonction.html. Vous faites ensuite !>script, puis tab, pour avoir une structure minimum. Vous pouvez copier/coller le code ci-dessous.

Ce qu'il faut voir :

Jusqu'à maintenant, on avait passé des valeurs en paramètres d'appel. Ici pour la fonction incrémentation, j'ai placé une variable i en paramètre d'appel, et c'est la valeur de i qui va être passée.

alert() est aussi une fonction. C'est une fonction native, c'est-à-dire qu'elle nous est fournie par le langage. Ce n'est pas nous qui l'écrivons.

Je fais un appel à la fonction incrementation. Et c'est la valeur de retour de cet appel qui va être passée au alert. La valeur de retour, c'est la valeur qui est retournée par le return.

#3 Comment sont passés les paramètres d'appel ? open

Au moment d'un appel à une fonction, les paramètres d'appel sont passés par copie dans une pile d'exécution. Voilà un lien vers Wikipédia si ça vous intéresse.

Ce qui est important, c'est de comprendre que la fonction travaille sur des copies locales des paramètres d'appels.

On ajoute alert(i) à la fin du script précédent.

On pourrait croire que la variable i est incrémentée en "passant" dans la fonction. Ce n'est pas le cas ! C'est la copie de i qui est incrémentée.

Ceci a une conséquence. N'espérez pas passer des variables en paramètres d'appel d'une fonction afin de les modifier dans la fonction, pour ensuite récupérer les variables modifiées. Ca ne marchera pas. Il faudra passer par un (ou plusieurs) return implantés dans la fonction.

Je vais créer ci-dessous une situation encore plus piégeuse que la précédente. Je mets le même nom à la variable globale et au paramètre de déclaration et je modifie un peu la fonction.

Ci-dessus, vous pourriez croire que le index du var index est passé à la fonction, qu'il est incrémenté de 1 et qu'il vaut donc 1 après l'appel. Et ce n'est pas le cas ! Pour les mêmes raisons que précédemment, à savoir que la fonction travaille sur des copies.

Il faut noter ici, que variables et paramètres de déclaration peuvent porter le même nom. Ils ne sont pas implantés aux mêmes emplacements mémoire. C'est même une situation courante.

Il faut préciser, mais c'est autre chose, qu'il y a des langages qui ne vous laisseraient pas modifier un argument d'entrée et qui déclencheraient une erreur, mais JavaScript ne le fait pas.

#4 Etude de cas open

On peut utiliser des variables globales dans les fonctions.

Je ne vais plus passer index en paramètre donc je l'enlève de la déclaration et de l'appel. La fonction travaille sur la variable globale index.

Variable déclarée en local donc undefined en dehors.

Ci-dessous, var index est locale donc l'utilisation de index en dehors de la fonction déclenche une erreur sur le console.log() car j'utilise une variable qui n'est pas déclarée.

On oublie le var. Elle devient globale

Si vous oubliez le var dans la déclaration d'une variable locale, elle devient globale. Il peut y avoir des conséquences. Si une autre variable globale index est déclarée ailleurs dans le programme, sa valeur sera écrasée.

Variable globale et variable locale avec le même nom

La variable locale et la variable globale ne sont pas dans les mêmes emplacements mémoire.

Dans la fonction, la variable globale est masquée par la variable locale. Vous ne pouvez pas y accéder.

#5 Les fonctions anonymes open

Il n'est pas obligatoire en JavaScript de donner un nom à une fonction au moment de la déclaration. Pourquoi faire ça ?? On aura besoin de déclarer des fonctions de cette manière quand on travaillera avec des gestionnaires d'événements.

Pour appeler la fonction, une solution, c'est de l'affecter à une variable et d'utiliser des parenthèses. Ce sont les parenthèses qui provoquent l'appel de la fonction. On dit aussi l'invocation de la fonction.

On va en profiter pour voir le typeof d'une variable à laquelle on a affecté une fonction. C'est un cas que l'on n'avait pas pu voir dans le tuto sur les variables.

#7 Absence de typage des paramètres de déclaration open

Vous l'avez peut-être remarqué, en JavaScript, au moment de la déclaration d'une fonction, on donne la liste des paramètres de déclaration, mais on ne précise pas leur type.

Je vais appeler deux fois la fonction ajouter(). Une première fois avec deux valeurs de type number et une deuxième fois avec deux valeurs de type string. Le langage me donne cette possibilité.

Dans le premier cas, on va avoir une addition de number avec pour résultat 5. Dans le second cas, une concaténation de chaîne avec pour résultat 23. L'interpréteur ira chercher le bon opérateur + en fonction du type des opérandes. Le + des number si ce sont des number ou le + des string (concaténation) si ce sont des string.

#8 Les fonctions récursives open

On parle de fonction récursive, lorsque l'on programme une fonction qui s'appelle elle-même. Cela peut surprendre, mais c'est très utilisé pour parcourir des structures de données arborescentes. La structure de données de base en informatique est l'arborescence. Nos documents HTML ont des structures de données arborescentes, nos systèmes de fichiers aussi.

La récursivité est rendue possible par la présence d'une pile d'exécution, dans laquelle JavaScript empile un contexte d'exécution à chaque appel d'une fonction. Les appels à la fonction dans la fonction elle-même peuvent ainsi se succéder sans "s'écraser" entres-eux.

Ici, je vais donner l'exemple classique du calcul d'une factorielle.

Empiler les appels et dépiler les résultats
Calcul de factorielle