Mutation en JavaScript : modifier une valeur sur place, et ce que ça casse

Une mutation modifie un objet ou un tableau existant au lieu d'en créer un nouveau. Utile, rapide, et responsable de bogues difficiles à localiser.
3 min de lecture
Believemy logo

Ajouter un élément à un tableau semble anodin. Si ce tableau a été transmis à trois endroits du programme, les trois voient le changement, sans avoir rien demandé.

C'est le propre de la mutation : elle ne produit pas de nouvelle valeur, elle modifie celle qui existe déjà, y compris pour tous ceux qui la détenaient.


Définition

Une mutation est une modification appliquée sur place à une valeur existante. Seuls les objets et les tableaux peuvent muter, parce qu'ils sont manipulés par référence. Les nombres et les chaînes, eux, ne changent jamais.

JAVASCRIPT
const original = [3, 1, 2];
const copieSupposee = original;

copieSupposee.push(4);
console.log(original); // [ 3, 1, 2, 4 ]

const vraieCopie = [...original];
vraieCopie.push(5);
console.log(original.length);   // 4
console.log(vraieCopie.length); // 5

copieSupposee n'est pas une copie : c'est un second nom pour le même tableau. Le Spread (...) en fabrique un vrai, indépendant.


Les méthodes de tableau, rangées en deux camps

La confusion vient de ce que les deux familles se ressemblent à l'écriture. Ce tableau à deux colonnes les sépare.

Modifient le tableauRenvoient un nouveau tableau
push, pop, shift, unshiftconcat, slice
splicefilter, toSpliced
sorttoSorted
reversetoReversed

Les trois méthodes commençant par to ont justement été ajoutées au langage pour offrir une version qui ne mute pas. Voir Array.sort() et slice() pour le détail de chacune.


Quand muter reste le bon choix

  • Sur une valeur locale. Un tableau construit dans une fonction et jamais sorti ne risque rien.
  • Sur de très gros volumes. Recopier un million d'éléments à chaque étape finit par se voir.
  • Dans un accumulateur explicite. Un Array.reduce() qui remplit son propre objet reste lisible et sûr.
Bon à savoir

La règle pratique tient en une phrase : mutez ce que vous avez créé, jamais ce que vous avez reçu. Un argument modifié est un Effet de bord que l'appelant n'a pas vu venir.


Questions fréquentes

Question

Comment repérer une mutation qui traîne ?

Le symptôme classique est une valeur qui change sans qu'aucune ligne visible ne la modifie. Geler la structure avec Object.freeze() pendant le développement fait remonter le coupable, puisque la modification lève alors une erreur au lieu de passer. Voir Immuabilité pour les limites du gel.


Question

Une chaîne de caractères peut-elle muter ?

Non. Toutes les méthodes de String (chaîne de caractères) renvoient une nouvelle chaîne, y compris celles qui semblent transformer l'original. Écrire texte.toUpperCase() sans récupérer le résultat ne change rien. La même remarque vaut pour les nombres et les booléens.


Question

Pourquoi mon tri modifie-t-il le tableau d'origine ?

Parce que sort() trie sur place et renvoie le même tableau, pas une copie. C'est le piège le plus fréquent de la famille, surtout quand le résultat est affecté à une nouvelle variable, ce qui donne l'illusion d'une copie. Utilisez toSorted(), ou triez une copie obtenue avec [...liste].

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.