Il s'agit des meilleures pratiques lorsque vous devez copier un objet en javascript.
Par exemple:
J'ai un objet { name: 'Dodo', method: function () { console.log(this.name) }}
;
J'ai besoin d'en créer une copie:
var obj = { name: 'Dodo', method: function () { console.log(this.name) } };
// what is better?
var copyUnderscore = _(obj).clone();
var copySimple = obj;
Quelle est la meilleure façon? Merci!
_.clone
Est complètement différent de l'affectation.
_.clone
Crée un nouvel objet et copie chaque valeur de l'original vers le nouvel objet.
Une affectation pointe simplement une variable sur l'objet qui existe déjà.
Supposons que vous aviez un chiot. Appelons-le Rex.
Si vous discutez de Rex avec quelqu'un, vous l'appellerez Rex, ou peut-être "le chien". Ces deux éléments font référence à l'animal en question. Une affectation est analogue à l'utilisation de différentes phrases pour votre animal de compagnie:
rex = {
type: 'Dog',
age: '12 Weeks',
name: "Rex",
fixed: false,
fix: function() {
this.fixed = true;
console.log(this.name + " Fixed.");
}
};
theDog = rex;
// Note the use of `===`, which checks for object identity.
// Assignment (as above) is the whole point of `===`
if (theDog === rex) {
alert("The Dog is the Same as Rex");
}
Lorsque vous changez quelque chose sur l'un, il change pour les deux références. Supposons donc que vous "répariez" Rex:
rex = {
type: 'Dog',
age: '12 Weeks',
name: "Rex",
fixed: false,
fix: function() {
this.fixed = true;
console.log(this.name + " Fixed.");
}
};
theDog = rex;
rex.fix();
alert("The Dog is " + (theDog.fixed ? "" : "not ") + "fixed");
alert("Rex is " + (rex.fixed ? "" : "not ") + "fixed");
theDog
est également corrigé.
Supposons maintenant que vous ayez cloné Rex. (Imaginons qu'il ne soit pas encore résolu pour des raisons d'argument).
rex = {
type: 'Dog',
age: '12 Weeks',
name: "Rex",
fixed: false,
fix: function() {
this.fixed = true;
console.log(this.name + " Fixed.");
}
};
theDog = rex;
otherDog = _.clone(rex);
console.log(theDog);
console.log(rex);
console.log(otherDog);
var message = rex === theDog ? "Rex is the same as the dog" : "Rex and the dog are different";
message += "\n";
message += rex === otherDog ? "Rex is the same as the other dog" : "Rex is different from the other dog";
message += "\n";
message += rex.fixed ? "Rex is fixed" : "Rex is not fixed";
message += "\n";
message += otherDog.fixed ? "Other dog is fixed" : "Other dog is not fixed";
alert(message);
otherDog.fix();
message = rex.fixed ? "Rex is fixed" : "Rex is not fixed";
message += "\n";
message += otherDog.fixed ? "Other dog is fixed" : "Other dog is not fixed";
alert(message);
<script src="http://underscorejs.org/underscore-min.js"></script>
Chaque valeur de rex
a été copiée dans otherDog
. Miraculeusement, "otherDog" est né à l'âge de 12 semaines. Mais la fixation de l'un va pas réparer l'autre.
Maintenant que rex
et theDog
sont le même chien, aucun n'est corrigé. Cependant, otherDog
est fixe. C'est un clone, pas le même animal.
Il y a quelques subtilités à se méfier. _.clone
Ne copie pas en profondeur. Cela signifie que tout objet ou tableau qui est une valeur dans l'objet cloné est copié par affectation vers le nouvel objet (voir le premier extrait pour un examen de ce que cela signifie).
Cela signifie que si rex
avait une propriété mother
qui était un objet représentant sa mère, elle serait partagée entre rex
et otherDog
. Toute modification de la mère de rex
serait propagée à otherDog
. Ce n'est pas si différent de la vraie vie; la mère biologique est une seule et même personne.
[~ # ~] modifier [~ # ~]
Autre remarque miraculeuse: le clonage d'un chien fixe produit un autre chien fixe. C'est là que la métaphore biologique se décompose.
MODIFIER ENCORE (juin 2018)
Il existe deux fonctionnalités ES6 supplémentaires qui pourraient intéresser les lecteurs de cette question:
Ce qui suit est identique à _.clone
(Copie les membres):
let x = {...rex};
Ce qui suit copie les membres dans un objet existant, puis renvoie cet objet:
let x = {}; let anotherReferenceToX = Object.assign(x, rex);
BONUS!
Il convient de noter que lodash en fait a une opération de clonage en profondeur . Vous pouvez également utiliser function (x) { return JSON.parse(JSON.stringify(x)) }
. Mais cela va étouffer les références circulaires, et pas le lodash.