Cloner un objet en javascript avec jQuery

Mai 2013

En Javascript, lorsqu'on copie une variable qui n'est pas d'un type primitif (booléen, nombre ou chaine de caractère), donc en gros : un objet ou une liste, la variable n'est pas dupliquée en mémoire, on obtient simplement une seconde référence qui pointe vers la même variable (en d'autres termes : un pointeur).

Voici un petit exemple pour illustrer ça :

// Création d'un objet
var original = {
	couleur: 'rouge',
	forme: 'carré'
};

// Copie de l'objet + modification de la copie
var copie = original;
copie.couleur = 'bleu';

alert(original.couleur); // bleu => l'original a été modifié !

Nous allons donc voir comment cloner un objet, comment en créer une copie conforme (100% identique) mais indépendante de l'original. On parle aussi de deep copy (par opposition à shallow copy qui ne copie pas la descendance).

La méthode la plus simple consiste à sérialiser la variable (en JSON), puis en la déserialisant. Cette technique n'est d'ailleurs pas propre à Javascript, elle est utilisée dans de nombreux langages comme C# ou PHP.

Pour ça, il faut utiliser les fonctions JSON.stringify() pour sérialiser, et sa réciproque : JSON.parse() pour déserialiser (c'est-à-dire construire une variable à partir d'une chaine JSON).

Sauf que comme d'habitude, ces fonctions ne sont pas supportées par tous les navigateurs (à tout hasard : Internet Explorer...). Heureusement, il existe des solutions pour transformer un objet Javascript en JSON :

Voici donc une fonction qui permet de dupliquer un objet en Javascript :

function clone(obj){
	try{
		var copy = JSON.parse(JSON.stringify(obj));
	} catch(ex){
		alert("Vous utilisez un vieux navigateur bien pourri, qui n'est pas pris en charge par ce site");
	}
	return copy;
}

Je n'ai pas implémenté le catch qui est sensé assurer la compatibilité avec les vieux navigateurs, je vous laisse le faire si vous trouvez ça utile. Mais sachez qu'Internet Explorer supporte JSON.stringify() et JSON.parse() depuis IE8 (sauf en mode de compatibilité...).

Sur internet, j'ai vu des extraits de code qui utilisent les fonctions uneval et eval à la place de JSON.*, c'est une très mauvaise idée, d'une part car uneval ne fonctionne que sur Firefox, et d'autre part parce que eval présente potentiellement une faille de sécurité car avec eval on peut exécuter n'importe quel code Javascript.

La page du jour est afficher les formules à la place des valeurs dans les cellules excel, bonne lecture.

Alternatives

Il existe d'autres méthodes que la sérialisation / désérialisation :

Méthode récursive

Cette technique consiste à copier l'objet (par référence), pour ensuite changer son prototype de manière à le "détacher" de l'original. C'est très technique et ça utilise des concepts avancés de la programmation orientée prototype, je vous déconseille de l'utiliser si vous n'êtes pas une rockstar en Javascript, mais vous pouvez toujours lire ces pages :

Changement de prototype

Ici il s'agit de parcourir récursivement tout l'objet, de manière copier séparément chacune des variables de type scalaire (booléen, nombre, string...), car les variables scalaires sont copiées par valeur et non par référence.

En général on utilise une fonction récursive pour faire ça, la condition d'arrêt (empêchant la récursion infinie) étant le type de la variable.

Encore faim ? allez lire ça : tilt shift !

0 commentaire
facultatif
Facebook Twitter RSS Email
Forum Excel
Venez découvrir le nouveau forum excel question/réponse à la stackoverflow.com !
Forum Excel
hit parade n'en a rien a foutre du W3C Positionnement et Statistiques Gratuites Vincent Paré