Cloner en profondeur un objet en JavaScript

Harshit Jindal 12 octobre 2023
  1. Copie superficielle vs copie profonde
  2. Méthodes de copie superficielle en JavaScript
  3. Méthodes de copie profonde en JavaScript
Cloner en profondeur un objet en JavaScript

JavaScript est un langage d’objets. Presque tout est un objet en JavaScript. Les booléens, les nombres, les chaînes, les dates, les mathématiques, l’expression régulière, les tableaux, les fonctions et les objets eux-mêmes sont tous des objets. Il s’agit d’un ensemble de paires clé-valeur comprenant divers attributs et méthodes. Ils sont stockés directement en mémoire et ne peuvent être copiés que par référence. Une variable ne stocke pas l’objet mais simplement une référence à cet objet en mémoire. Ainsi, lorsque nous essayons de copier une variable d’objet, nous finissons par créer une référence supplémentaire au même objet. Cette méthode est appelée copie superficielle. Ce n’est pas idéal car nous ne voulons pas que la modification de l’objet d’origine affecte son clone. Cela crée le besoin d’une méthode pour cloner en profondeur l’objet. Ce didacticiel explique comment cloner en profondeur un objet en JavaScript.

Copie superficielle vs copie profonde

Une copie superficielle est une copie au niveau du bit de l’objet. Le nouvel objet créé avec succès copie les primitives telles que les nombres, les valeurs booléennes et les chaînes, mais ne copie aucune référence aux objets. Seules les adresses de référence aboutissent à un pointeur pointant vers le même objet. Toutes les modifications apportées à l’objet d’origine sont reflétées dans la copie superficielle.

D’un autre côté, une copie profonde ne copie pas uniquement l’adresse/référence de l’objet d’origine mais l’ensemble de l’objet. Le nouvel objet créé n’a aucune dépendance vis-à-vis de l’objet copié. JavaScript nous fournit diverses méthodes intégrées pour copier un objet, mais la copie superficielle est le comportement par défaut dans la plupart d’entre elles.

Méthodes de copie superficielle en JavaScript

Nous aborderons brièvement les méthodes de copie superficielle pour vous informer de certaines des mauvaises façons de copier en profondeur.

Utilisez la syntaxe Spread pour cloner peu profondément un objet en JavaScript

Nous pouvons cloner un objet en créant un nouvel objet, puis en utilisant la syntaxe de propagation pour énumérer le contenu d’un objet à l’intérieur comme le sien. Cela semble être la bonne façon, mais cela crée une copie superficielle des données.

const obj = {
  a: 1,
  b: {c: 2}
}

const clone = {...obj};  // creates a shallow copy

obj.b.c = 5;
console.log(clone.b.c);  // outputs 5

Dans le code ci-dessus, nous utilisons la syntaxe spread pour créer une copie superficielle de l’objet. Nous modifions ensuite l’une des propriétés de l’objet référencé dans l’objet d’origine et montrons que la propriété est modifiée dans l’objet cloné.

Utilisez le Object.assign() pour cloner peu profondément un objet en JavaScript

La méthode object.assign() affecte une copie superficielle de l’objet à une nouvelle variable d’objet. Il prend deux arguments: cible et source. La target est généralement une paire de parenthèses vides utilisées pour représenter l’objet vide dans lequel copier; c’est un argument optionnel mais le transmettre garantit que nous ne finirons pas par changer l’objet d’origine. Le deuxième argument est l’objet à copier.

const obj = {
  a: 1,
  b: {c: 2}
}

const clone = Object.assign({}, obj);  // creates a shallow copy

obj.b.c = 5;
console.log(clone.b.c);  // outputs 5

Dans le code ci-dessus, nous utilisons Object.assign() pour créer une copie superficielle de l’objet. Nous modifions ensuite l’une des propriétés de l’objet référencé dans l’objet d’origine et montrons que la propriété est modifiée dans l’objet cloné.

Méthodes de copie profonde en JavaScript

Utilisez JSON.parse() et JSON.stringify() pour cloner en profondeur un objet en JavaScript

JSON.stringify() est utilisé pour convertir un objet JavaScript en une chaîne JSON et JSON.parse() est utilisé pour convertir une chaîne JSON en objet JavaScript. Nous pouvons envelopper JSON.parse() autour de JSON.stringify() pour d’abord convertir l’objet JavaScript en chaîne JSON, puis l’analyser pour obtenir une copie de l’objet.

var user = {name: 'Harshit', age: 21, Profession: 'Software Engineer'};
let fakeDeepCopy = JSON.parse(JSON.stringify(user));

Cette méthode crée une copie complète, mais uniquement pour les objets sans fonctions. Il a des problèmes avec les dépendances circulaires comme les autres objets référencés. L’ordre des propriétés de l’objet copié peut également différer de l’objet d’origine. Donc, cette méthode est une bonne astuce si nous avons un objet simple avec quelques types de données primitifs, mais elle n’est pas recommandée pour le monde réel.

Utiliser le clonage profond natif pour cloner en profondeur un objet en JavaScript

Nous pouvons utiliser l’algorithme de sérialisation du module Node.js v8 pour cloner en profondeur un objet. Bien qu’il soit limité à certains types de données intégrés, il préserve les références dans les données clonées. Cela nous permet de copier plusieurs structures cycliques et récursives qui n’étaient pas prises en charge par la méthode JSON.

const v8 = require('v8');

const structuredClone = obj => {
  return v8.deserialize(v8.serialize(obj));
};

Nous désérialisons puis sérialisons l’objet tout comme le stringify et l’analyse des méthodes JSON. Mais il préserve les dépendances circulaires et est légèrement meilleur.

Utilisez la bibliothèque Lodash pour cloner en profondeur un objet en JavaScript

La bibliothèque Lodash a des fonctions pour la copie superficielle et profonde, à savoir clone et clonedeep. C’est une excellente bibliothèque qui nous permet d’importer uniquement les fonctions dont nous avons besoin et non la bibliothèque complète. La méthode clonedeep fonctionne en copiant récursivement la valeur puis en préservant tous les héritages d’objet, créant une copie fidèle de l’objet.

const lodashClonedeep = require('lodash.clonedeep');
let obj = {a: 1, b: {c: 2}} let deepClone = lodashClonedeep(obj);

Ici, nous chargeons la fonction clonedeep de lodash et l’utilisons pour cloner en profondeur l’objet. C’est une bibliothèque bien testée et maintenue, mais elle ne peut être utilisée qu’avec Node.js et non Vanilla JavaScript.

Utilisez la méthode jQuery extend() pour cloner en profondeur un objet en JavaScript

Nous pouvons utiliser .extend() de jQuery pour copier superficiellement et copier en profondeur un objet. C’est la méthode de clonage en profondeur la plus fiable sans perte de données ni corruption de données. Sa fonction principale est de fusionner deux ou plusieurs objets. Mais peut également être utilisé pour cloner un objet. Il prend les arguments suivants: [deep], target, object1 ..... objectN.

  1. [deep]: C’est un argument optionnel. Sa seule valeur autorisée est true. S’il est passé dans la fonction, la fonction crée une copie complète de l’objet. Sinon, il forme une copie superficielle.
  2. target: l’objet à étendre. Il recevra tous les objets fusionnés.
  3. object1, ..., objectN: Ce sont les objets à fusionner/cloner dans un nouvel objet.
let obj = {a: 1, b: {c: 2}} let shallowClone =
    $.extend({}, obj);                    // creates a shallow copy
let deepClone = $.extend(true, {}, obj);  // creates a deep copy

Une solution plus évidente peut être simplement d’itérer toutes les propriétés de l’objet source et de les répliquer dans un nouvel objet. Toutes les méthodes décrites ci-dessus sont compatibles avec tous les principaux navigateurs.

Harshit Jindal avatar Harshit Jindal avatar

Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.

LinkedIn

Article connexe - JavaScript Object