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 :
Code JavaScript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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) :
Code JavaScript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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[attribute] === 'object' && originalObject[attribute] !== null){ 
                deepProto(originalObject[attribute], deepCopy[attribute]); 
            } 
        } 
    } 
    deepProto(originalObject, deepCopy); 
  
    return deepCopy; 
} 
  
var copy = clone(originalObject);

Deep-copy test :
Code JavaScript : Sélectionner tout
1
2
3
4
5
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 :
Code JavaScript : Sélectionner tout
1
2
3
4
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.

N'hésitez pas à donner votre avis

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