IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

JavaScript - Réaliser une copie parfaite d'objet

Le , par Gugelhupf

0PARTAGES

Auteur : Gokan EKINCI
Date de première publication : 2015-12-27
Licence : CC BY-NC-SA

Objectif : Réaliser une copie parfaite d’objet

Contraintes :


  • L’objet copié ne devra pas impacter l’objet d’origine si on modifie un attribut (effet indésirable), nous appelerons ce principe le « deep-copy ». On testera le « deep-copy » à partir de l’opérateur « === ».
  • L’objet copié devra pouvoir exécuter les méthodes de l’objet d’origine.
  • L’objet copié devra être du même type que l’objet d’origine.


Nous allons créer un objet de type Foo :
function Foo(levelName, obj){
this.levelName = levelName;
this.deep = obj;
}

Foo.prototype.method1 = function(){
console.log("This method works !");
}

var originalObject = new Foo("Level 1",
new Foo("Level 2",
new Foo("Level 3", null)
)
);

console.log(originalObject.levelName); // Level 1
console.log(originalObject.deep.levelName); // Level 2
console.log(originalObject.deep.deep.levelName); // Level 3

Solutions connues pour copier un objet :


ES6
var copy = Object.assign({}, originalObject);


jQuery (Mod 1)
var copy = jQuery.extend({}, originalObject);


jQuery (Mod 2)
var copy = jQuery.extend(true, {}, originalObject);


JSON
var copy = JSON.parse(JSON.stringify(originalObject));



Ma simple solution (peut ne pas fonctionner avec une version d'Internet Explorer inférieur à 11) :
function clone(originalObject){
if((typeof originalObject !== 'object') || originalObject === null){
throw new TypeError("originalObject parameter must be an object which is not null");
}

var deepCopy = JSON.parse(JSON.stringify(originalObject));

// Une petite récursivité
function deepProto(originalObject, deepCopy){
deepCopy.__proto__ = Object.create(originalObject.constructor.prototype);
for(var attribute in originalObject){
if(typeof originalObject === 'object' && originalObject !== null){
deepProto(originalObject, deepCopy);
}
}
}
deepProto(originalObject, deepCopy);

return deepCopy;
}

var copy = clone(originalObject);

Deep-copy test :



console.log(copy.levelName);
console.log(copy.deep.levelName);
console.log(copy.deep.deep.levelName);
console.log(originalObject.deep === copy.deep);
console.log(originalObject.deep.deep === copy.deep.deep);


ES6 output
Level 1
Level 2
Level 3
true
true
=> Pas de deep-copy :-(



jQuery (Mod 1) output
Level 1
Level 2
Level 3
true
true
=> Pas de deep-copy :-(



jQuery (Mod 2) output
Level 1
Level 2
Level 3
true
true
=> Pas de deep-copy :-(



JSON output
Level 1
Level 2
Level 3
false
false
=> Deep-copy :-)



Ma simple solution output
Level 1
Level 2
Level 3
false
false
=> Deep-copy :-)




Test de type et méthode :



console.log(copy.constructor.name); // Type test1
console.log(copy.deep.constructor.name); // Type test2
copy.method1(); // Method test1
copy.deep.method1(); // Method test2



ES6 output
Object
Object
TypeError: copy.method1 is not a function
=> copy n'est pas de type Foo :-(
=> les méthodes de Foo ne sont pas reconnues :-(



jQuery (Mod 1) output
Object
Object
This method works !
This method works !
=> copy n'est pas de type Foo :-(
=> les méthodes de Foo sont reconnues :-)



jQuery (Mod 2) output
Object
Object
This method works !
This method works !
=> copy n'est pas de type Foo :-(
=> les méthodes de Foo sont reconnues :-)



JSON output
Object
Object
TypeError: copy.method1 is not a function
=> copy n'est pas de type Foo :-(
=> les méthodes de Foo ne sont pas reconnues :-(



Ma simple solution output
Foo
Foo
This method works !
This method works !
=> copy est de type Foo :-)
=> les méthodes de Foo sont reconnues :-)




Conclusion des tests :



Deep-copy
Méthode reconnue
Méthode reconnue (deep level)
Type
Type (deep level)


ES6
Echec
Echec
Echec
Echec
Echec


jQuery (Mod 1)
Echec
Succès
Succès
Echec
Echec


jQuery (Mod 2)
Echec
Succès
Succès
Echec
Echec


JSON
Succès
Echec
Echec
Echec
Echec


Ma simple solution
Succès
Succès
Succès
Succès
Succès



Vous êtes arrivé à la fin de ce mini-tutoriel pour copier des objets en JavaScript. N'hésitez pas à consulter mon profil et mon site (https://gokan-ekinci.appspot.com/) pour plus d'infos.

:fleche: N'hésitez pas à donner votre avis ;)

Vous avez lu gratuitement 190 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !