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)); |
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 :
|
|||||
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 :-) |
|
|||||
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 :-) |
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 |
N'hésitez pas à donner votre avis