par , 27/12/2015 à 02h35 (2149 Affichages)
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 :
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) :
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 :
|
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 :
|
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