Découper avec des fonctions
Découper un programme en fonctions réutilisables.
Objectifs
À la fin de cette leçon, vous saurez :
- définir et appeler une fonction, en distinguant paramètres et arguments ;
- retourner une valeur avec
return— et comprendre ce qui se passe sans lui ; - composer des fonctions entre elles, comme des briques ;
- découper un problème en petites unités à responsabilité unique.
🔗 Pour vous rafraîchir la mémoire : conditions et boucles
Le problème : du code dupliqué
let a = 5;
let b = 10;
console.log(`Somme : ${a + b}`);
let c = 20;
let d = 30;
console.log(`Somme : ${c + d}`);
Deux fois la même intention (« affiche la somme de deux nombres »), deux implémentations. À l'échelle d'un programme réel — des milliers de lignes — cette duplication devient ingérable : une correction à faire dix fois, dix occasions de se tromper.
La fonction répond exactement à cela : elle donne un nom à un bloc de code, précise ses entrées et sa sortie. Le calcul s'écrit une fois, se réutilise partout :
function addition(a, b) {
return a + b;
}
console.log(addition(5, 10)); // 15
console.log(addition(20, 30)); // 50
console.log(addition(100, -7)); // 93
Anatomie complète, vocabulaire précis
function addition(a, b) { // déclaration : nom + paramètres
return a + b; // corps : le travail + la sortie
}
addition(5, 10); // appel : nom + arguments
addition: le nom — il doit dire ce que fait la fonction (un verbe souvent) ;a,b: les paramètres — des variables locales qui existeront pendant l'exécution ;5,10: les arguments — les valeurs réellement passées lors de CET appel ;return a + b;: la valeur de retour — ce que l'expressionaddition(5, 10)vaudra.
Le déroulement mérite d'être suivi précisément, car c'est le cœur du sujet :
1. JavaScript rencontre addition(5, 10)
2. Il crée un petit espace de travail : a = 5, b = 10
3. Il exécute le corps : a + b → 15
4. return rend 15 ET TERMINE la fonction immédiatement
5. L'appel entier « devient » 15, là où il était écrit
6. L'espace de travail (a, b) disparaît — rien ne fuit vers l'extérieur
Ce point 6 annonce le chapitre 4 (portée des variables) : les paramètres et variables déclarées dans une fonction n'existent qu'à l'intérieur. C'est une protection, pas une contrainte.
Conséquence immédiate du point 4 : tout code après un return exécuté est mort :
function exemple(x) {
return x * 2;
console.log("jamais atteint"); // code mort
}
Et plusieurs return peuvent coexister — seul celui atteint en premier agit :
function signe(n) {
if (n > 0) return "positif";
if (n < 0) return "négatif";
return "zéro"; // cas restant
}
Cette forme « gardes successives puis cas par défaut » est très lisible ; adoptez-la sans crainte.
Sans return : undefined silencieux
function additionAffichee(a, b) {
console.log(a + b); // affiche... mais ne REND rien
}
const total = additionAffichee(4, 4);
console.log(total); // undefined !
La fonction a bien affiché 8, mais son résultat n'existe pas pour le programme : sans return, toute fonction renvoie undefined. La distinction fondamentale :
Fonction qui calcule (return) | Fonction qui affiche (console.log) | |
|---|---|---|
| Résultat réutilisable ? | oui : const t = somme(3, 4) | non : perdu après l'affichage |
| Peut servir dans un calcul ? | oui : somme(1, 2) * 10 | non |
| Testable facilement ? | oui : comparer valeurs | pénible : capturer du texte |
Règle professionnelle : les fonctions calculent et retournent ; c'est l'appelant qui décide d'afficher. Vous écrirez donc surtout des fonctions à return, et vous réserverez console.log aux points d'entrée du programme.
function aire(r) {
return Math.PI * r * r; // calcule
}
const a1 = aire(2); // l'appelant utilise
console.log(aire(2)); // ... ou affiche
console.log(aire(2) + aire(3)); // ... ou compose
Paramètres par défaut
Un paramètre peut avoir une valeur de repli si l'argument manque :
function saluer(nom, politesse = "Bonjour") {
return `${politesse}, ${nom} !`;
}
console.log(saluer("Paul")); // Bonjour, Paul !
console.log(saluer("Paul", "Bonsoir")); // Bonsoir, Paul !
Très utilisé pour rendre des options facultatives proprement.
Les fonctions se composent
Une fonction peut appeler d'autres fonctions — c'est ainsi qu'on construit des programmes lisibles, couche par couche :
function aire(r) {
return Math.PI * r * r;
}
function peri(r) {
return 2 * Math.PI * r;
}
function decritCercle(r) {
return `Rayon ${r} → aire ${aire(r).toFixed(2)}, périmètre ${peri(r).toFixed(2)}`;
}
console.log(decritCercle(2));
// Rayon 2 → aire 12.57, périmètre 12.57
decritCercle ne connaît pas la formule de l'aire : elle utilise celles qui existent. Ce principe (chaque niveau s'appuie sur le précédent) porte loin : vos serveurs du chapitre 19 seront exactement construits ainsi.
La règle d'or : une fonction, une responsabilité
// À ÉVITER : fait trois métiers
function traiterCommande(commande) {
const total = commande.prix * commande.quantite;
commande.statut = "payée";
console.log(`Payé : ${total} €`);
return total;
}
// MIEUX : trois briques, chacune testable seule
function calculerTotal(commande) {
return commande.prix * commande.quantite;
}
function marquerPayee(commande) {
commande.statut = "payée";
}
function confirmerPaiement(commande) {
marquerPayee(commande);
const total = calculerTotal(commande);
console.log(`Payé : ${total} €`);
return total;
}
Comment savoir si votre fonction respecte la règle ? Test du nom : si vous ne pouvez pas la nommer sans dire « et », elle en fait trop. Ce réflexe sera approfondi au chapitre 28 (responsabilités et cohésion) — mais il commence ici, maintenant, avec ces petites fonctions.
Au passage : la syntaxe fléchée
Vous croiserez vite une deuxième écriture des fonctions :
const addition = (a, b) => a + b;
console.log(addition(2, 3)); // 5
(paramètres) => expression : même idée, notation plus courte, omniprésente dans le code moderne (et dans ce cursus dès le chapitre front-end). Pour aujourd'hui, maîtrisez la forme function ; reconnaissez simplement la flèche quand vous la voyez.
Exercice
- Écrivez
somme(a, b)et testez-la sur trois couples, dont un avec un négatif. - Écrivez
estPair(n)qui retournetrueoufalse. - Écrivez
majuscule(texte)utilisant.toUpperCase(). - Écrivez
signe(n)retournant « positif », « négatif » ou « zéro ». - Écrivez
presente(nom, age)retournantBonjour Paul, vous avez 20 ans.— puis appelez-la pour deux personnes. - Écrivez
aire(r)(π·r²) etperi(r)(2πr), puisficheCercle(r)qui compose les deux pour retourner une ligne descriptive. - Piège final : que vaut
console.log(somme(2, 3))sisommeaffiche au lieu de retourner ? Écrivez la version fautive, observezundefined, corrigez.
Résumé
- Une fonction = nom + paramètres + corps + valeur retournée ; l'appel exécute et « devient » la valeur retournée.
returntermine immédiatement ; sans lui,undefined.- Les fonctions calculent, l'appelant affiche — séparation qui rend tout composable et testable.
- Paramètres par défaut pour les options ; composition de fonctions pour bâtir en couches.
- Une fonction, une responsabilité — le test du nom.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Solutions commentées
function somme(a, b) {
return a + b;
}
console.log(somme(5, 3)); // 8
console.log(somme(-4, 9)); // 5
console.log(somme(0, 0)); // 0
function estPair(n) {
return n % 2 === 0; // l'expression EST déjà un booléen
}
console.log(estPair(8)); // true
console.log(estPair(7)); // false
function majuscule(texte) {
return texte.toUpperCase();
}
console.log(majuscule("cours")); // COURS
function signe(n) {
if (n > 0) return "positif";
if (n < 0) return "négatif";
return "zéro";
}
function presente(nom, age) {
return `Bonjour ${nom}, vous avez ${age} ans.`;
}
console.log(presente("Paul", 20)); // Bonjour Paul, vous avez 20 ans.
console.log(presente("Awa", 31)); // Bonjour Awa, vous avez 31 ans.
function aire(r) {
return Math.PI * r * r;
}
function peri(r) {
return 2 * Math.PI * r;
}
function ficheCercle(r) {
return `Rayon ${r} : aire ≈ ${aire(r).toFixed(2)}, périmètre ≈ ${peri(r).toFixed(2)}`;
}
console.log(ficheCercle(2));
// Rayon 2 : aire ≈ 12.57, périmètre ≈ 12.57
Notez estPair : inutile d'écrire if (...) { return true; } else { return false; } — la comparaison n % 2 === 0 produit déjà le booléen. Retourner directement l'expression est plus court et tout aussi clair.
Question 7 : le piège démonté
function sommeAffichee(a, b) {
console.log(a + b); // affiche 5...
}
console.log(sommeAffichee(2, 3));
// 5 ← affiché depuis DANS la fonction
// undefined ← ce que la fonction RETOURNE
Deux lignes pour un seul appel : le 5 vient du console.log interne, le undefined est la valeur de retour manquante. La version correcte retourne, et laisse l'affichage à l'appelant. Si vous avez vu ce comportement une fois en vrai, vous le reconnaîtrez instantanément dans six mois — c'était le but de la question.