Essayer de coder ← Retour aux sujets

Déclarer et appeler

function

Une fonction regroupe du code réutilisable. En JavaScript, c'est aussi une valeur : on peut la ranger dans une variable, la passer en argument, la renvoyer.

function carre(n) { return n * n; }
Déclaration classique
const carre = function (n) { … };
Expression de fonction
const carre = (n) => n * n;
Fonction fléchée (return implicite pour une expression)
function f(a, b = 10) { … }
Paramètre avec valeur par défaut
function somme(...nombres) { … }
Paramètre « reste » : un tableau de tous les arguments
return valeur;
Renvoie une valeur (sinon la fonction renvoie undefined)
carre.js
function carre(n) {
  return n * n;
}

const cube = (n) => n * n * n;

console.log(carre(7), cube(3));
console.log(carre(carre(2)));
Affichage
49 27
16

Fonctions passées en argument

callback

Une fonction peut en recevoir une autre (un callback). C'est le principe de map, filter, setTimeout et des écouteurs d'événements.

[1, 2, 3].map((x) => x * 2)
Applique la fonction à chaque élément
tableau.filter((x) => x > 1)
Garde les éléments qui passent le test
tableau.reduce((t, x) => t + x, 0)
Réduit à une seule valeur (somme, maximum…)
setTimeout(() => { … }, 1000)
Appelle la fonction dans une seconde
bouton.addEventListener("click", f)
Appelle f à chaque clic
function compteur() { let n = 0; return () => ++n; }
Fermeture : la fonction renvoyée se souvient de n
callbacks.js
const nombres = [1, 2, 3, 4, 5];

const doubles = nombres.map((x) => x * 2);
const pairs = nombres.filter((x) => x % 2 === 0);
const somme = nombres.reduce((total, x) => total + x, 0);

console.log(doubles.join(" "), "|", pairs.join(" "), "|", somme);
Affichage
2 4 6 8 10 | 2 4 | 15

⚙️ 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

FormeExempleÀ savoir
déclarationfunction carre(n) { return n * n; }utilisable avant sa ligne de définition (remontée)
expressionconst carre = function (n) { … };utilisable seulement après sa définition
fléchéeconst 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).

parametres.js
function salue(nom = "invité", ...titres) {
  return `Bonjour ${nom} ${titres.join(" ")}`.trim();
}

console.log(salue("Lina", "(élève)", "(NSI)"));
console.log(salue());
Affichage
Bonjour 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.

extremes.js
function extremes(tableau) {
  return { min: Math.min(...tableau), max: Math.max(...tableau) };
}

const { min, max } = extremes([12, 7, 15, 9]);
console.log(min, max);
Affichage
7 15

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.

fermeture.js
function creerCompteur() {
  let n = 0;
  return function () {
    n += 1;
    return n;
  };
}

const compteur = creerCompteur();
console.log(compteur(), compteur(), compteur());
Affichage
1 2 3

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 ».

factorielle.js
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));
Affichage
120 3628800

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).

⚠️ Erreurs fréquentes

Oublier le return

À éviter
faux.js
function carre(n) { n * n; }        // renvoie undefined
Correct
correct.js
function carre(n) { return n * n; }

Appeler la fonction au lieu de la passer

À éviter
faux.js
setTimeout(afficher(), 1000);       // appelle afficher tout de suite !
Correct
correct.js
setTimeout(afficher, 1000);         // passe la fonction ; elle sera appelée plus tard

Avec des parenthèses, on exécute la fonction et on passe son résultat. Sans parenthèses, on passe la fonction elle-même. Pour lui donner des arguments : setTimeout(() => afficher("x"), 1000).

Une fonction fléchée qui renvoie un objet

À éviter
faux.js
const f = () => { nom: "Lina" };      // un bloc avec une étiquette : renvoie undefined
Correct
correct.js
const f = () => ({ nom: "Lina" });    // parenthèses autour de l'objet

Modifier sans le vouloir un tableau reçu en argument

Les tableaux et objets sont passés par référence : function ajoute(t) { t.push(1); } modifie le tableau de l'appelant. Pour ne pas le toucher, travaille sur une copie : const copie = [...t];.

Oublier let ou const : variable globale par accident

Dans une fonction, total = 0; sans mot-clé crée (en mode non strict) une variable globale qui peut être écrasée par un autre bout de code. Déclare toujours avec let ou const.

Une récursion sans fin

Si l'argument ne se rapproche pas du cas de base, la pile d'appels déborde (RangeError: Maximum call stack size exceeded). Vérifie : « quel est le cas le plus simple ? » et « l'argument diminue-t-il ? ».

📋 Aide-mémoire

  • function f(a, b = 0, ...reste) { return … } ; flèche : (a) => a * 2 (pas de return pour une expression, ({ … }) pour un objet).
  • Sans return, la fonction renvoie undefined ; plusieurs résultats : on renvoie un objet ou un tableau.
  • Arguments manquants = undefined ; les valeurs par défaut et le paramètre reste évitent les cas tordus.
  • Callback : on passe f (sans parenthèses) ; map / filter / reduce / setTimeout / addEventListener en reçoivent.
  • Fermeture : une fonction interne garde accès aux variables de la fonction qui l'a créée.
  • Récursion = cas de base + appel plus petit ; déclare toujours avec let / const.