Effet de bord en JavaScript : tout ce qu'une fonction fait en plus de renvoyer une valeur

Un effet de bord est toute action d'une fonction observable en dehors d'elle : écriture, affichage, appel réseau ou modification d'un argument.
3 min de lecture
Believemy logo

Une fonction censée calculer un total écrit aussi une ligne dans un journal, met à jour un compteur global et envoie une mesure à un service d'analyse. Son nom ne dit rien de tout cela.

Ces actions supplémentaires portent un nom : les effets de bord. Elles ne sont ni interdites ni suspectes, mais elles changent la façon dont une fonction se teste et se relit.


Définition

Un effet de bord est toute action d'une fonction observable depuis l'extérieur, en dehors de la valeur qu'elle renvoie. Modifier une variable partagée, écrire dans le stockage du navigateur, afficher quelque chose, appeler un service : tout cela en fait partie.

JAVASCRIPT
let journal = [];

function calculerPur(nombres) {
  return nombres.reduce((total, n) => total + n, 0);
}

function calculerAvecEffet(nombres) {
  journal.push("calcul de " + nombres.length + " valeurs"); // effet de bord
  return calculerPur(nombres);
}

console.log(calculerAvecEffet([1, 2, 3])); // 6
console.log(journal);                      // [ 'calcul de 3 valeurs' ]

Les deux fonctions renvoient la même valeur. La seconde laisse en plus une trace dans le programme, et cette trace est invisible pour qui lit seulement son appel.


Les formes les plus courantes

  • Modifier un argument reçu : une Mutation que l'appelant n'a pas demandée. La plus insidieuse des quatre.
  • Écrire une variable extérieure : compteur global, cache, drapeau d'état.
  • Toucher au monde extérieur : localStorage, un appel fetch(), un affichage dans la console.
  • Lancer une erreur : un throw détourne le flux du programme, ce qui est aussi un effet.


Le problème n'est pas l'effet, c'est sa dispersion

Un programme sans effet ne sert à rien : il ne montre rien et n'enregistre rien. Ce qui coûte cher, c'est un effet caché au milieu d'une fonction qui semble ne faire qu'un calcul.

La pratique consiste à rassembler les effets à un seul endroit, en général la lisière de l'application, et à garder le reste en Fonction pure. Concrètement, une fonction calcule et renvoie, une autre prend ce résultat et l'écrit quelque part.

Bon à savoir

Un signal simple pour les repérer : si le nom de la fonction commence par un verbe de calcul mais que son corps contient une écriture, il y a deux responsabilités dans une seule fonction.


Questions fréquentes

Question

Un console.log() est-il vraiment un effet de bord ?

Techniquement oui, puisqu'il écrit à l'extérieur de la fonction. En pratique il est inoffensif : il ne change aucune donnée et disparaît sans conséquence. La question mérite d'être posée seulement quand la sortie console devient un mécanisme de journalisation sur lequel d'autres systèmes s'appuient.


Question

Comment tester une fonction qui en produit ?

En remplaçant la dépendance par un double contrôlé, un mock, et en vérifiant qu'elle a bien été appelée. C'est faisable mais toujours plus long qu'un test de fonction pure. La meilleure économie consiste souvent à extraire le calcul dans une fonction séparée, testée directement.


Question

Le Array.forEach() produit-il forcément un effet ?

Presque toujours, oui, puisqu'il ne renvoie rien : son seul intérêt est de faire quelque chose à chaque tour. Quand vous cherchez à produire une valeur plutôt qu'à agir, Array.map() ou Array.reduce() expriment mieux l'intention et laissent la donnée d'origine tranquille.

Termes connexes

Découvrez notre glossaire JavaScript

Tous les mots de JavaScript expliqués simplement : mots-clés, objets natifs, méthodes, erreurs et concepts. Définitions claires et exemples qui tournent, pour apprendre et pour se dépanner.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.