Googler pour "javascript clone object" donne des résultats vraiment bizarres, certains sont désespérément obsolètes et d'autres trop complexes, n'est-ce pas aussi simple que cela:
let clone = {...original};
Y a-t-il un problème avec ça?
C'est bon pour le clonage superficiel . Le la propagation d'objet est une partie standard d'ECMAScript 2018 .
Pour le clonage en profondeur, vous aurez besoin de solution différente .
const clone = {...original}
à cloner peu profond
const newobj = {...original, prop: newOne}
pour ajouter immuablement un autre accessoire à l'original et le stocker en tant que nouvel objet.
EDIT: Lorsque cette réponse a été publiée, la syntaxe {...obj}
n'était pas disponible dans la plupart des navigateurs. De nos jours, vous devriez pouvoir l'utiliser (à moins que vous n'ayez besoin de supporter IE 11).
Utilisez Object.assign.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
Cependant, cela ne fera pas un clone profond. Il n’existe pas encore de méthode autochtone de clonage en profondeur.
EDIT: Comme @Mike 'Pomax' Kamermans est mentionné dans les commentaires, vous pouvez profondément cloner des objets simples (c'est-à-dire sans prototypes, fonctions ou références circulaires) en utilisant JSON.parse(JSON.stringify(input))
si vous ne souhaitez pas utiliser json.parse (json.stringify (objet)), vous pouvez créer de manière récursive des copies de valeurs-clés:
function copy(item){
let result = null;
if(!item) return result;
if(Array.isArray(item)){
result = [];
item.forEach(element=>{
result.Push(copy(element));
});
}
else if(item instanceof Object && !(item instanceof Function)){
result = {};
for(let key in item){
if(key){
result[key] = copy(item[key]);
}
}
}
return result || item;
}
Mais le meilleur moyen est de créer une classe pouvant renvoyer un clone
class MyClass{
data = null;
constructor(values){ this.data = values }
toString(){ console.log("MyClass: "+this.data.toString(;) }
remove(id){ this.data = data.filter(d=>d.id!==id) }
clone(){ return new MyClass(this.data) }
}
Si les méthodes que vous avez utilisées ne fonctionnent pas bien avec des objets impliquant des types de données tels que Date, essayez ceci.
Importer _
import * as _ from 'lodash';
Objet clone profond
myObjCopy = _.cloneDeep(myObj);
Suite à la réponse de @marcel, j’ai trouvé que certaines fonctions manquaient encore sur l’objet cloné. par exemple.
function MyObject() {
var methodAValue = null,
methodBValue = null
Object.defineProperty(this, "methodA", {
get: function() { return methodAValue; },
set: function(value) {
methodAValue = value || {};
},
enumerable: true
});
Object.defineProperty(this, "methodB", {
get: function() { return methodAValue; },
set: function(value) {
methodAValue = value || {};
}
});
}
où sur MyObject je pouvais cloner methodA mais methodB était exclu. Ceci est dû au fait qu'il manque
enumerable: true
ce qui signifiait qu'il ne figurait pas dans
for(let key in item)
Au lieu de cela je suis passé à
Object.getOwnPropertyNames(item).forEach((key) => {
....
});
qui comprendra des clés non énumérables.
J'ai également constaté que le prototype (proto) n'était pas cloné. Pour cela, j'ai fini par utiliser
if (obj.__proto__) {
copy.__proto__ = Object.assign(Object.create(Object.getPrototypeOf(obj)), obj);
}
PS: Frustrant que je ne puisse pas trouver une fonction intégrée pour le faire.
Toutes les méthodes ci-dessus ne gèrent pas le clonage profond d'objets où il est imbriqué sur n niveaux. Je n'ai pas vérifié ses performances par rapport aux autres mais c'est court et simple.
Le premier exemple ci-dessous montre le clonage d'objet à l'aide de Object.assign
qui clone jusqu'au premier niveau.
var person = {
name:'saksham',
age:22,
skills: {
lang:'javascript',
experience:5
}
}
newPerson = Object.assign({},person);
newPerson.skills.lang = 'angular';
console.log(newPerson.skills.lang); //logs Angular
Utilisation de l'objet d'approche profonde ci-dessous
var person = {
name:'saksham',
age:22,
skills: {
lang:'javascript',
experience:5
}
}
anotherNewPerson = JSON.parse(JSON.stringify(person));
anotherNewPerson.skills.lang = 'angular';
console.log(person.skills.lang); //logs javascript