DEV Community

Gravisto
Gravisto

Posted on ‱ Edited on

1 1

đŸ‡«đŸ‡· [ANGULAR] Transformez Votre Code en Forteresse : Adoptez l'ImmutabilitĂ© !

Dans le domaine de la programmation fonctionnelle, l’immutabilitĂ© des donnĂ©es est un des concepts les plus importants mais aussi un des plus durs Ă  assimiler. Il est beaucoup plus simple de travailler avec des objets mutables et dans la grande majoritĂ© des cas le code n’en est pas affectĂ©. Alors prĂ©fĂ©rer l’immutabilitĂ© des donnĂ©es dans son application web, ça peut sembler s’infliger des contraintes supplĂ©mentaires sans fondement, pourtant ça ne viendrait pas Ă  l’idĂ©e d’un collĂ©gien de faire ses exercices dans son manuel empruntĂ© au CDI. Traiter toutes ses donnĂ©es comme un livre empruntĂ©, c’est garantir que tous les lecteurs accĂšdent aux donnĂ©es non corrompues. Dans cet article, on va expliquer la diffĂ©rence entre les donnĂ©es mutables et immutables, ce que cela implique dans votre code javascript et appliquer les bonnes pratiques de manipulation de donnĂ©es.

Le cas des variables mutables

En javascript, seuls les objets sont mutables. Mais si vous avez dĂ©jĂ  entendu que tout est objet en javascript alors c’est perdu, tout serait donc mutable ? La rĂ©alitĂ© est un peu plus complexes que ça. En effet, il existe 7 types primitifs immutables, parmi eux : string, number, boolean, undefined, etc. Mais il existe un objet wrapper autour de chaque type primitif. Donc en principe, tout ce avec quoi on interagit quand on Ă©crit du code javascript est mutable.

Mais in fine, ça veut dire quoi (im)mutable ? On dira qu’une valeur est immutable si pour l’éditer on doit recrĂ©er une valeur. Ouvrez la console et essayez le code suivant, la chaine de caractĂšre associĂ©e ne sera pas Ă©ditĂ©e :

const foo = "Coucou le monde!";
foo[1] = "s";
console.log(foo) // output: "Coucou le monde!"
Enter fullscreen mode Exit fullscreen mode

memes sur l'immutabilité


⚠ Dans le cas de mutabilitĂ©, on parle de la valeur (dans l’exemple : "Coucou le monde!") et pas de la variable (dans l’exemple : foo) associĂ©e. La variable peut donc changer autant de fois de valeur, cela ne qualifiera pour autant pas le caractĂšre mutable de ces valeurs. ⚠

Inversement, pour une liste, on peut modifier n’importe quel Ă©lĂ©ment, en ajouter et en enlever sans recrĂ©er une liste Ă  chaque fois.

Les mots clefs const et readonly n’ont rien Ă  voir avec la mutabilitĂ© des valeurs. Ils garantissent juste que l’on ne peut rĂ©assigner de valeurs. On n'en parlera donc pas.

En pratique, les valeurs mutables que l’on utilise sont les objets et les listes.


â„č On parlera de mĂ©thode mutable si la mĂ©thode modifie la valeur de l’objet sur laquelle elle s’applique. Inversement, un mĂ©thode immutable crĂ©era une nouvelle rĂ©fĂ©rence avec les nouvelles valeurs. En pratique, on parle de fonction pure.â„č

Pourquoi travailler avec des données immutables ?

Maintenant qu’on a vu la diffĂ©rence entre valeur mutable et valeur immutable, on va donner deux exemples en Angular pour saisir l’impact que la mutabilitĂ© des valeurs peut avoir sur le rĂ©sultat de notre code.

ChangeDetector d’Angular

stackblitz about cdr

Dans cet exemple de code, on veut crĂ©er une animation dans laquelle chaque Ă©lĂ©ment de la liste s’affiche aprĂšs chaque seconde. Mais pourquoi l’animation du haut ne se met pas Ă  jour ? La diffĂ©rence se situe sur les mĂ©thodes pour mettre Ă  jour notre liste.

crd bad example

cdr good example

Le changeDetector d’Angular ne dĂ©tecte pas les mutations de valeur. Donc si on ne crĂ©e pas une nouvelle valeur, le composant (OnPush) ou le pipe (pure) ne mettra pas Ă  jour la valeur dans la vue, mĂȘme si les valeurs sont correctes.

Il faut bien comprendre que dans les deux cas la liste est bel et bien mise Ă  jour, mais Angular ne peut dĂ©tecter ces changements car pour lui la liste mutĂ©e est la mĂȘme.


â„č Muter (= modifier une liste de maniĂšre mutable) une liste c’est lui ajouter, enlever ou modifier un ou plusieurs Ă©lĂ©ment. On ne peut pas changer une liste de maniĂšre immutable, il faut la recrĂ©er.â„č

Partage de valeur

stackblitz about immutability

Dans ce deuxiĂšme exemple, nous avons deux composants qui partagent un objet configuration. On change sa propriĂ©tĂ© color parce qu’à la place d’une valeur hexadĂ©cimale, on veut une valeur RGB pour le CSS. Malheureusement, si je change la valeur pour l’un, la valeur change pour les deux.

immutable bad example

immutable good example

Pour répondre au problÚme, on peut appliquer nos changement à la liste de maniÚre immutable. On verra dans la partie suivante comment faire dans le cas général en Javascript.

Ces problĂ©matiques ne sont pas propres Ă  Angular, ni mĂȘme au code Javascript mais quand on manipule beaucoup de donnĂ©es, on a intĂ©rĂȘt Ă  appliquer des changements immutables aux valeurs que l’on manipule. Ces deux exemples sont simples puisqu’il n'y a que deux-trois composants mais quand les donnĂ©es ont des parcours plus complexes, ce sont gĂ©nĂ©ralement des bugs trĂšs difficiles Ă  dĂ©celer.

Fake it till you make it

poisson avec une aile de requin acroché dessus

Comment travailler avec des données mutables ? Faßtes semblant que les données soient immutables. Ainsi, à chaque update de valeur, il faut recréer son objet.

Le problĂšme de cette mĂ©thode c’est qu’elle nĂ©cessite de bien connaĂźtre les mĂ©thodes mutables associĂ©es Ă  son objet. Pour les objets issus de librairies, bon courage car il faudra tester Ă  la main. Pour les objets natifs comme Array, MDN saura vous rĂ©pondre.

Vous pouvez dĂšs Ă  prĂ©sent bannir sort et accueillir sa petite sƓur mutable toSorted tout frais du standard 2023 d’EcmaScript (cf.NouveautĂ©s 2023 JS). Plus simplement, toutes les mĂ©thodes qui s’écrivent sous la forme newValue = oldValue.method() ont de bonnes chances d’ĂȘtre immutables.


â„č Pour aller plus loin, il existe des librairies JS (immutable& immer) qui implĂ©mentent diverses structures de donnĂ©es immutables pour remplacer les objets natifs javascript mutables. Ces structures de donnĂ©es sont plus sĂ»res Ă  utiliser mais nĂ©cessitent que les dĂ©veloppeurs soient formĂ©s sur ces librairies. Leur grand intĂ©rĂȘt est surtout au niveau des performances.â„č

Conclusion

Comme le prĂ©cise la documentation MDN au sujet de l’immutabilitĂ©, il est dur de travailler qu’avec des structures de donnĂ©es immutables si aucune sĂ©mantique de langage ne le garantit (Rappel, le mot clef const ne garantit pas l’immutabilitĂ© des donnĂ©es, seulement de la variable).

Dans le cas de Javascript, cela est avant tout un contrat entre développeurs que les mutations ne sont pas de bons pattern de développement (Par exemple en utilisant Object.freeze ou des librairies spécialisées).

Comme on l’a vu dans la partie d’exemple, le grand intĂ©rĂȘt de l’immutabilitĂ© est d’éviter des bugs oĂč les mutations ne se transposent pas sur lĂ  oĂč on les fait, ou pire qu’elles se transposent lĂ  oĂč on ne les fait pas.

Enfin, l’immutabilitĂ© est l’un des principes clefs de la programmation fonctionnelle et ouvre les portes aux fonctions pures.

TL;DR: Avoid in place mutation, prefer replacing

Source

JavaScript data types and data structures - JavaScript | MDN
Immutable - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
How everything is Object in JavaScript ?
Prototype and Protypal Inheritance in JavaScript
Primitive - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
Immutability
How is almost everything in Javascript an object?

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

The Most Contextual AI Development Assistant

Pieces.app image

Our centralized storage agent works on-device, unifying various developer tools to proactively capture and enrich useful materials, streamline collaboration, and solve complex problems through a contextual understanding of your unique workflow.

đŸ‘„ Ideal for solo developers, teams, and cross-company projects

Learn more