open

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 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éclarationParamètres utilisés à l'appel
    Paramètres formelsParamètres effectifs
    ParamètresArguments
    Paramètres de déclarationParamè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 faîtes 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. C'est pas nous qui l'écrivons.

Je place 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. J'ai mis un lien dans la description vers Wikipedia 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. C'est 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 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