⚙️ Le cours : écrire et réutiliser du code
Une fonction donne un nom à un bloc de code qu'on peut appeler autant de fois qu'on veut, avec des valeurs différentes. Découper un programme en petites fonctions (une idée par fonction) le rend plus lisible et plus simple à corriger. Tu en utilises déjà : console.log, Math.max, parseInt sont des fonctions.
Trois façons de définir une fonction
| Forme | Exemple | À savoir |
| déclaration | function carre(n) { return n * n; } | utilisable avant sa ligne de définition (remontée) |
| expression | const carre = function (n) { … }; | utilisable seulement après sa définition |
| fléchée | const carre = (n) => n * n; | syntaxe courte ; pas de this propre ; idéale pour les callbacks |
La fonction fléchée n'a pas besoin de return quand le corps est une seule expression ; avec des accolades { }, le return redevient obligatoire. Une fonction fléchée à un seul paramètre peut omettre les parenthèses : x => x * 2.
Paramètres et arguments
JavaScript est tolérant : appeler une fonction avec trop peu d'arguments donne undefined aux paramètres manquants, avec trop d'arguments ignore les autres. Deux outils rendent cela propre : la valeur par défaut (nom = "invité") et le paramètre reste (...titres, qui rassemble les arguments en trop dans un tableau).
function salue(nom = "invité", ...titres) {
return `Bonjour ${nom} ${titres.join(" ")}`.trim();
}
console.log(salue("Lina", "(élève)", "(NSI)"));
console.log(salue());
AffichageBonjour Lina (élève) (NSI)
Bonjour invité
Renvoyer une valeur, ou plusieurs
return termine la fonction et renvoie une valeur ; sans return, le résultat est undefined. Pour renvoyer plusieurs résultats, on renvoie un objet ou un tableau, que l'on décompose à l'appel.
function extremes(tableau) {
return { min: Math.min(...tableau), max: Math.max(...tableau) };
}
const { min, max } = extremes([12, 7, 15, 9]);
console.log(min, max);
Portée et fermetures
Une variable déclarée avec let ou const dans une fonction n'existe que dans cette fonction. Mais une fonction définie à l'intérieur d'une autre garde l'accès aux variables de son parent, même après la fin du parent : c'est une fermeture (*closure*). C'est ainsi qu'on fabrique une variable privée, comme le compteur ci-dessous.
function creerCompteur() {
let n = 0;
return function () {
n += 1;
return n;
};
}
const compteur = creerCompteur();
console.log(compteur(), compteur(), compteur());
Des fonctions pour transformer des données
Parce qu'une fonction est une valeur, les tableaux offrent des méthodes qui en reçoivent une : map transforme chaque élément, filter en sélectionne, reduce les combine en une seule valeur, find, some, every… Ces fonctions d'ordre supérieur remplacent beaucoup de boucles (voir Tableaux).
Récursivité
Une fonction récursive s'appelle elle-même. Il lui faut un cas de base qui arrête la récursion et un appel sur un cas plus petit. Sans cas de base, JavaScript s'arrête avec l'erreur « Maximum call stack size exceeded ».
function fact(n) {
if (n <= 1) {
return 1; // cas de base
}
return n * fact(n - 1); // appel sur un cas plus petit
}
console.log(fact(5), fact(10));
Fonctions fléchées et this
Une fonction classique a son propre this, qui dépend de la façon dont on l'appelle ; une fonction fléchée reprend le this de l'endroit où elle est écrite. C'est pourquoi on l'utilise pour les callbacks à l'intérieur d'une méthode, mais pas pour définir une méthode d'objet (voir Objets).