• 20 heures
  • Facile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_certifying

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Mis à jour le 29/07/2019

Modularisez votre code grâce aux fonctions

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Dans ce chapitre, vous allez découvrir comment décomposer un programme en sous-parties appelées des fonctions.

Introduction : le rôle des fonctions

Pour comprendre l'intérêt des fonctions, revenons sur notre algorithme de préparation d'un plat de pâtes issu du chapitre d'introduction.

Début
    Sortir une casserole
    Mettre de l'eau dans la casserole
    Mettre la casserole sur le feu
    Tant que l'eau ne bout pas
      Attendre
    Verser les pâtes dans la casserole
    Tant que les pâtes ne sont pas cuites
        Attendre
    Verser les pâtes dans une passoire
    Remuer la passoire pour faire couler l'eau
    Remettre les pâtes dans la casserole
    Goûter
    Tant que les pâtes sont trop fades
        Ajouter du sel
        Goûter
    Si on préfère le beurre à l'huile
        Ajouter du beurre
    Sinon
        Ajouter de l'huile
Fin

Voici le même algorithme. écrit d'une manière différente.

Début
    Faire bouillir de l'eau
    Cuire les pâtes dans l'eau
    Egoutter les pâtes
    Assaisonner les pâtes
Fin

La première version détaille toutes les actions individuelles à réaliser. La seconde décompose la recette en sous-étapes regroupant plusieurs actions individuelles. Cette version est plus concise et plus facile à interpréter, mais elle introduit des concepts relatifs au domaine de la cuisine comme cuire, égoutter, ou assaisonner. On peut envisager de réutiliser ces concepts pour réaliser d'autres recettes, par exemple la préparation d'un plat de riz.

Jusqu'à présent, vos programmes étaient écrits sur le modèle du premier algorithme : des actions individuelles qui s'enchaînent. Vous allez maintenant apprendre à les concevoir sous la forme d'un ensemble de sous-étapes. En JavaScript, ces sous-étapes sont appelées des fonctions.

Découverte des fonctions

Une fonction est un regroupement d'instructions qui réalise une tâche donnée.

Voici un exemple basique utilisant une fonction.

function direBonjour() {
  console.log("Bonjour !");
}

console.log("Début du programme");
direBonjour();
console.log("Fin du programme");

Observez ci-dessous le résultat de son exécution.

https://www.codevolve.com/api/v1/publishable_key/A0AD115498F500753B5BD9AE4A991924?content_id=dc333b44-0fbb-4b18-965a-d40634b5605d

Les paragraphes suivants vont permettre d'expliquer ce résultat.

Déclaration d'une fonction

Observons la première partie du programme d'exemple.

function direBonjour() {
  console.log("Bonjour !");
}

Cet extrait permet de créer une fonction nomméedireBonjour(). Elle n'est constituée que d'une seule instruction qui affiche sur la console le message "Bonjour !".

L'opération de création d'une fonction s'appelle la déclaration. Voici sa syntaxe.

// Déclaration d'une fonction nommée maFonction
function maFonction() {
  // Instructions de la fonction
}

La déclaration d'une fonction s'effectue à l'aide du mot-clé JavaScriptfunction suivi du nom de la fonction et d'une paire de parenthèses. Les instructions qui composent la fonction constituent le corps de la fonction. Ces instructions sont placées entre accolades et indentées.

Appel d'une fonction

Voici la seconde partie de notre programme d'exemple.

console.log("Début du programme");
direBonjour();
console.log("Fin du programme");

La première et la troisième instructions affichent des messages dans la console.  La deuxième effectue un appel à la fonctiondireBonjour() déclarée plus haut.

L'appel d'une fonction s'effectue en écrivant le nom de la fonction suivi d'une paire de parenthèses. 

// ...
maFonction(); // Appel de la fonction maFonction
// ...

L'appel d'une fonction déclenche l'exécution des instructions qui la constituent, puis l'exécution reprend à l'endroit où la fonction a été appelée. Ce fonctionnement est illustré par le schéma ci-dessous.

Mécanisme d'appel d'une fonction
Mécanisme d'appel d'une fonction

Avantages des fonctions

Lorsqu'on cherche à résoudre un problème complexe, il est généralement efficace de le décomposer en sous-problèmes plus simples.

Les fonctions permettent d'appliquer ce principe à la création de logiciels : on va décomposer le programme en écrivant plusieurs fonctions, chacune dédiée à un objectif particulier. Le programme fera appel aux fonctions au fur et à mesure de son exécution.

Ecrit sous la forme d'une combinaison de fonctions, le programme sera plus lisible et plus facile à faire évoluer qu'un programme écrit de manière monobloc. De plus, il sera parfois possible de réutiliser certaines fonctions dans d'autres programmes.

Enfin, la création d'une fonction permet de lutter contre la duplication de code : plutôt que de dupliquer le même code dans un programme, on centralise ce code sous la forme d'une fonction et on y fait appel depuis tous les endroits où c'est nécessaire.

Possibilités des fonctions

Valeur de retour

Voici une variante de notre programme d'exemple.

function direBonjour() {
  return "Bonjour !";
}

console.log("Début du programme");
const resultat = direBonjour();
console.log(resultat); // "Bonjour !"
console.log("Fin du programme");

Ce programme produit exactement le même résultat que le précédent.

Dans cet exemple, le corps de la fonctiondireBonjour() a été modifié : l'instructionconsole.log("Bonjour !") a été remplacée par la lignereturn "Bonjour !".

L'utilisation du mot-cléreturn dans une fonction permet de lui donner une valeur de retour. Son appel produit un résultat qui correspond à la valeur placée juste après lereturn dans la fonction. Ce résultat peut être récupéré par le programme appelant. Ici, la fonctiondireBonjour() renvoie la valeur chaîne"Bonjour !". Cette valeur est stockée par le programme dans la variableresultat, qui est ensuite affichée.

Une fonction incluant une instructionreturn renvoie une valeur de retour lorsqu'elle est appelée : cette valeur résulte de l'évaluation de l'expression située immédiatement après lereturn.

// Déclaration d'une fonction nommée maFonction
function maFonction() {
  // Calcul de la valeur de retour
  // ...
  return valeurRetour;
}

// Récupération de la valeur de retour de maFonction
let valeur = maFonction();
// ...

Cette valeur de retour peut être de n'importe quel type (nombre, chaîne, etc). En revanche, une fonction ne peut renvoyer qu'une seule valeur.

Rien n'oblige à récupérer la valeur de retour d'une fonction, mais dans ce cas, cette valeur est "oubliée" par le programme qui appelle la fonction !

On peut simplifier un peu notre exemple en affichant directement le résultat de l'appel à la fonctiondireBonjour() sans utiliser de variable. Ici, la valeur de retour dedireBonjour() est directement affichée dans la console.

function direBonjour() {
  return "Bonjour !";
}

console.log(direBonjour()); // "Bonjour !"

Variables locales

Il est possible de déclarer des variables à l'intérieur d'une fonction, comme dans l'exemple ci-dessous.

function direBonjour() {
  const message = "Bonjour !";
  return message;
}

console.log(direBonjour()); // "Bonjour !"

La fonctiondireBonjour() déclare une variable nomméemessage, puis renvoie sa valeur.

Les variables déclarées dans le corps d'une fonction sont appelées des variables locales. En effet, elles ne sont utilisables qu'à l'intérieur de la fonction. Ainsi, l'exécution du programme suivant provoquera une erreur.

function direBonjour() {
  const message = "Bonjour !";
  return message;
}

console.log(direBonjour()); // "Bonjour !"
console.log(message); // Erreur : la variable message n'existe pas ici

A chaque appel d'une fonction qui déclare des variables locales, ces variables sont recréées. On peut donc appeler plusieurs fois la même fonction, et chaque appel sera parfaitement indépendant des autres.

On nomme portée d'une variable l'ensemble des endroits où elle est accessible. La portée d'une variable locale se limite au corps de la fonction dans laquelle elle est déclarée.

Ne pas pouvoir utiliser de variables locales en dehors des fonctions où elles sont déclarées peut sembler une limitation. C'est au contraire un double avantage :

  • Une fonction peut être conçue comme une entité autonome et réutilisable.

  • Un programme peut déclarer ses propres variables et utiliser autant de fonctions que nécessaire, sans se préoccuper des variables locales qui y sont déclarées. 

Passage de paramètres

Un paramètre est une information dont une fonction a besoin pour jouer son rôle. Les paramètres d'une fonction sont définis entre parenthèses juste après le nom de la fonction. On peut ensuite utiliser leur valeur dans le corps de la fonction. 

La valeur d'un paramètre est fournie au moment de l'appel de la fonction : on dit que cette valeur est passée en paramètre. On appelle argument la valeur donnée à un paramètre lors d'un appel.

Modifions notre exemple pour construire un message de bienvenue personnalisé.

function direBonjour(prenom) {
  const message = `Bonjour, ${prenom} !`;
  return message;
}

console.log(direBonjour("Baptiste")); // "Bonjour, Baptiste !"
console.log(direBonjour("Sophie")); // "Bonjour, Sophie !"

La déclaration de la fonction ‌direBonjour() a été modifiée : elle contient à présent un paramètre nommé prenom.

Dans cet exemple, le premier appel à la fonctiondireBonjour() est fait avec l'argument"Baptiste" et le second avec l'argument"Sophie". Dans le premier cas, le paramètreprenom reçoit la valeur"Baptiste" et dans le second, la valeur"Sophie".

Voici la syntaxe générale de la déclaration d'une fonction acceptant des paramètres. Leur nombre n'est pas limité, mais il est rarement nécessaire de dépasser 3 ou 4 paramètres.

// Déclaration de la fonction maFonction
function maFonction(param1, param2, ...) {
  // Instructions pouvant utiliser param1, param2, ...
}

// Appel de la fonction maFonction
// param1 reçoit la valeur de arg1, param2 la valeur de arg2, ...
maFonction(arg1, arg2, ...);

La portée des paramètres d'une fonction se limite au corps de cette fonction. Ainsi, on peut utiliser comme argument une variable externe portant le même nom qu'un paramètre. L'exemple suivant est donc parfaitement valide.

function direBonjour(prenom) {
  // Ici, prenom est le paramètre de la fonction
  const message = `Bonjour, ${prenom} !`;
  return message;
}

// Ici, prenom est une variable utilisée comme argument
let prenom = "Baptiste";
console.log(direBonjour(prenom)); // "Bonjour, Baptiste !"
prenom = "Thomas";
console.log(direBonjour(prenom)); // "Bonjour, Thomas!"

Lors d'un appel à une fonction acceptant des paramètres, le nombre et l'ordre des paramètres doivent être respectés. Observez l'exemple suivant.

function presentation(prenom, age) {
  console.log(`Tu t'appelles ${prenom} et tu as ${age} ans`);
}

presentation("Garance", 10); // "Tu t'appelles Garance et tu as 10 ans"
presentation(6, "Prosper"); // "Tu t'appelles 6 et tu as Prosper ans"

Lors du second appel, les valeurs données aux paramètres sont inversées :prenom reçoit la valeur 6 etage reçoit la valeur"Prosper".

Fonctions anonymes

Il existe d'autres manières de créer des fonctions en JavaScript. En voici un exemple.

const bonjour = function(prenom) {
  const message = `Bonjour, ${prenom} !`;
  return message;
}

console.log(bonjour("Thomas")); // "Bonjour, Thomas !"

La fonction créée ci-dessus est anonyme et directement affectée à la variable  bonjour. La valeur de cette variable est donc une fonction. Cette manière de créer une fonction est appelée expression de fonction.

La syntaxe pour créer une fonction anonyme et l'affecter à une variable est la suivante.

// Affectation d'une fonction anonyme à la variable maVariable
const maVariable = function(param1, param2, ...) {
  // Instructions pouvant utiliser param1, param2, ...
}

// Appel de la fonction anonyme
// param1 reçoit la valeur de arg1, param2 la valeur de arg2, ...
maVariable(arg1, arg2, ...);

Les dernières évolutions du langage JavaScript ont introduit une syntaxe plus concise pour créer des fonctions anonymes. L'exemple suivant est strictement équivalent au précédent.

const bonjour = (prenom) => {
  const message = `Bonjour, ${prenom} !`;
  return message;
}

console.log(bonjour("Thomas")); // "Bonjour, Thomas !"

Cette syntaxe est appelée fonction fléchée (fat arrow function).

// Affectation d'une fonction anonyme à la variable maVariable
const maVariable = (param1, param2, ...) => {
  // Instructions pouvant utiliser param1, param2, ...
}

// Appel de la fonction anonyme
// param1 reçoit la valeur de arg1, param2 la valeur de arg2, ...
maVariable(arg1, arg2, ...);

Dans certains cas particuliers, on peut simplifier la syntaxe des fonctions fléchées :

  • Lorsque le corps de la fonction se limite à une seule ligne, on peut écrire son résultat sans créer de blocs de code avec des accolades. Dans ce cas, l'instruction  return  est implicite.

  • Lorsque la fonction n'a qu'un seul argument, on peut omettre les parenthèses autour de celui-ci.

// Dificile de faire plus concis !
const bonjour = prenom => `Bonjour, ${prenom} !`;

console.log(bonjour("Thomas")); // "Bonjour, Thomas !"

Les fonctions sont essentielles en JavaScript et sont utilisées sans cesse.

Comment (bien) programmer avec les fonctions

Créer des fonctions à bon escient

Une fonction peut utiliser les mêmes éléments qu'un programme classique : variables, conditions, boucles, etc. Une fonction peut même faire appel à une autre fonction, ce qui ouvre des possibilités infinies pour construire nos programmes.

Il convient toutefois de rester raisonnable et de ne pas multiplier artificiellement le nombre de fonctions d'un programme, sous peine de compliquer sérieusement sa compréhension (c'est le syndrome du code spaghetti). Il vaut mieux essayer de créer des fonctions ayant chacune un rôle bien défini et minimiser les interdépendances entre fonctions.

Utiliser les fonctions prédéfinies de JavaScript

Sans les nommer ainsi, nous avons déjà rencontré plusieurs fonctions prédéfinies de JavaScript commeprompt() oualert(). Le langage vous propose un nombre important de fonctions qui répondent à des besoins variés. En programmation comme ailleurs, il est rarement utile de réinventer la roue et il est important de privilégier l'utilisation de ces fonctions existantes plutôt qu'une réécriture manuelle. 

Voici un exemple utilisant deux des nombreuses fonctions mathématiques offertes par JavaScript.

console.log(Math.min(4.5, 5)); // 4.5
console.log(Math.min(19, 9));  // 9
console.log(Math.min(1, 1));   // 1

console.log(Math.random()); // Un nombre aléatoire entre 0 et 1

La fonctionMath.min() renvoie le minimum des nombres passés en paramètres. La fonctionMath.random() génère un nombre aléatoire entre 0 et 1.

Nous découvrirons d'autres fonctions prédéfinies dans la suite de ce cours.

Limiter la complexité des fonctions

Le corps d'une fonction doit garder un niveau de complexité faible et ne pas être trop long. Il n'y a pas de maximum universel, mais au-delà d'une vingtaine de lignes de code, la question de la décomposition d'une fonction en sous-fonctions doit se poser.

Bien nommer fonctions et paramètres

Comme pour les variables, le nommage des fonctions et des paramètres joue un rôle important dans la lisibilité du programme. Les recommandations sont les mêmes : choisir des noms qui expriment précisément le rôle et respecter la norme camelCase.

A vous de jouer !

Carré d'un nombre

https://www.codevolve.com/api/v1/publishable_key/A0AD115498F500753B5BD9AE4A991924?content_id=d63ff90e-beca-40e2-9d9f-d2d878347ef5

Minimum de deux nombres

https://www.codevolve.com/api/v1/publishable_key/A0AD115498F500753B5BD9AE4A991924?content_id=e2f026bc-bc86-442d-b88e-2a36a59a5d8e

Calculatrice

https://www.codevolve.com/api/v1/publishable_key/A0AD115498F500753B5BD9AE4A991924?content_id=ffaadb66-8e5a-4763-a0db-ae55ede5a9c5

TL;DR : Résumons !

  • Une fonction est un regroupement d'instructions qui réalise une tâche donnée. En JavaScript, une fonction est créée à l'aide du mot-clé function.

  • Écrire un programme sous forme d'un ensemble de fonctions plutôt qu'en un seul bloc permet de gagner en lisibilité et en modularité.

  • L'appel d'une fonction déclenche l'exécution des instructions qui la constituent, puis l'exécution reprend à l'endroit où la fonction a été appelée.

  • Les variables déclarées dans le corps d'une fonction sont appelées des variables locales. Leur portée se limite au corps de la fonction.

  • Une fonction peut renvoyer une valeur grâce au mot-clé  return  , ou ne rien renvoyer (on parle alors de procédure). Elle peut également accepter ou non des paramètres, qui sont les données dont elle a besoin pour fonctionner.

  • Il existe plusieurs manières de créer des fonctions en JavaScript. La première est la déclaration de fonction :

// Déclaration d'une fonction nommée maFonction
function maFonction() {
// Instructions de la fonction
}
maFonction(); 
// Appel de la fonction maFonction
  •  Une autre possibilité est d'utiliser une expression de fonction. Cette expression peut être affectée à une variable car en JavaScript, la valeur d'une variable peut être une fonction. Les expressions de fonction sont souvent utilisées pour créer des fonctions anonymes.

// Affectation d'une fonction anonyme à la variable maVariable
const maVariable = function(param1, param2, ...) {
// Instructions pouvant utiliser param1, param2, ...
}

// Appel de la fonction anonyme
// param1 reçoit la valeur de arg1, param2 la valeur de arg2, ...
maVariable(arg1, arg2, ...);

  •  JavaScript offre depuis peu une syntaxe plus concise pour créer des fonctions anonymes : la fonction fléchée (fat arrow function).

// Affectation d'une fonction anonyme à la variable maVariable
constmaVariable=(param1,param2,...)=>{
// Instructions pouvant utiliser param1, param2, ...
}
// Appel de la fonction anonyme
// param1 reçoit la valeur de arg1, param2 la valeur de arg2, ...
maVariable(arg1,arg2,...);
  • Il est important de créer des fonctions ayant un rôle bien défini et de limiter leur complexité. Le nom de la fonction, souvent basé sur un verbe à l'infinitif exprimant une action, doit refléter son rôle. JavaScript offre de nombreuses fonctions prédéfinies qui peuvent simplifier la tâche du programmeur.

Exemple de certificat de réussite
Exemple de certificat de réussite