Typescript

Devenir le maître des clones avec structuredClone()

Robin Jeanne, Consultant Senior @DeliaTechnologies
Robin Jeanne, Consultant Senior @DeliaTechnologies
March 10, 2023
10 min

Si vous avez déjà travaillé un peu en javascript/typescript, il y a de grandes chances que vous soyez tombés sur des problématiques de clonage.

Pour ceux qui préfèrent les cas pratiques, on peut imaginer le cas suivant : prenons un objet Employé, avec une interface de ce type :

Nous sommes sur une IHM permettant de modifier les rôles associés à des employés. Ceux-ci sont affichés dans un tableau, chaque ligne propose un bouton pour ouvrir une modale d'édition, avec un bouton "Annuler" et un bouton "Valider". Classique, non ?

En développeur consciencieux, vous avez pensé à faire quelque chose comme :

Cependant, vous allez vite vous rendre compte d'une chose : toutes les modifications réalisées sur le nouvel objet impactent l’ancien. Car vous n’avez pas cloné l’objet, vous avez juste réalisé un pointeur.

Quelques définitions ?

Avant d'aller plus loin, il est important de ne pas oublier certaines choses :

Comment cloner superficiellement un objet ?

Dans certains cas, on peut s’en sortir avec un simple clonage superficiel, et nous allons voir rapidement les techniques qui nous permettent de réaliser un clonage superficiel.

La syntaxe Spread

Mais si, vous savez, c'est ça :

Je vous invite à lire la documentation Mozilla sur la syntaxe Spread.

Mais, que serait-il arrivé si obj avait contenu des tableaux, des sous-objets ou mieux, des méthodes ? Oui, le clonage n’est que superficiel.

Petit point à connaître : seules sont copiées les propriétés énumérables de votre objet. Les méthodes n’en sont pas.

Les méthodes Object

Encore une fois, je ne vais pas vous faire un détail de chacune de ces méthodes, mais je vous invite à consulter les différentes documentations : Assign(), Create(), FromEntries().

Un point intéressant : Create() vous permet de créer un clone superficiel qui partagera les attributs de l’objet d’origine, tant que l’attribut du nouvel objet n’aura pas été surchargé. Assign() n’a pas ce comportement et va générer une copie superficielle décorrélée.

Assign(), Create() permettent d’appliquer le prototype (et donc les méthodes) au nouvel objet. Pas FromEntries().

JSON.stringify()

Celle-là est un peu plus astucieuse dans l'idée, mais fonctionne :

Enfin, ça fonctionnera tant que vous n'avez pas de date par exemple. Vous allez perdre toutes les informations liées au prototype ou tous les types qui ne sont pas supportés en json.

Vous pouvez également dire adieux à vos méthodes.

Comment réaliser un clonage profond ?

Pendant une période de temps malheureusement trop longue, il n’existait pas de méthode native javascript ou typescript permettant de faire du clonage profond.

Et si on utilisait Lodash ?

Lodash est une librairie javascript qui, avouons le, a beaucoup aidé et propose un tas de méthodes utilitaires vraiment pratiques, surtout quand on remonte quelques années dans le temps.

Mais avons-nous encore besoin de lodash aujourd'hui ? Pas sur !

La librairie n'apporte en fait plus grand chose si on prend en compte l'évolution de l'ECMAScript et les navigateurs modernes.

Ah oui, sauf pour ce satané DeepClone.

Installation de lodash dans un projet Angular - Vision d'artiste

Ça serait un peu dommage d'installer une librairie usine à gaz dans votre joli projet juste pour ça, non ? Oui, ça vaut également pour JQuery.

structuredClone, notre sauveur ?

La méthode structuredClone() permet de créer un clone profond, incroyable, non ?

Il faut noter que cette méthode ne fait pas partie de l’ECMAScript, mais elle est maintenant largement adoptée par la plupart des plateformes :

Comptabilité des plateformes avec structureClone() sur MDN, en janvier 2023

A noter que la compatibilité avec les webworkers n’est pas encore tout à fait là, mais il y a du progrès ! Il est même possible de trouver des polyfills pour assurer la comptabilité avec les “vieux” navigateurs !

Est-ce qu’on peut tout cloner avec ?

Malheureusement, non.

Conclusion

Pour devenir un maître de la manipulation d’objet et du clonage en typescript / javascript, n’oubliez pas la différence entre clonage profond et superficiel.

Et surtout, vous n’avez probablement pas besoin de cette librairie supplémentaire. Je vous invite également à aller plus loin, vous renseigner sur les fonctions pures et impures (d'expérience, elles ne sont jamais loin quand on en arrive à parler de clonage profond).

D'autres articles pour vous

Tous nos articles →
photo camille

Envie de rejoindre l'aventure ?

Réservez un moment avec notre équipe RH en quelques clics, pour voir ensemble le meilleur moyen de nous rejoindre. Vous avez des questions sur Delia Technologies ? C'est le moment de les poser !

Rencontrer notre équipe