Hva er den mest effektive måten å klone et JavaScript-objekt på? Jeg har sett obj = eval(uneval(o));
bli brukt, men det er ikke standard og støttes bare av Firefox.
Jeg har gjort ting som obj = JSON.parse(JSON.stringify(o));
men stiller spørsmål ved effektiviteten.
Jeg har også sett rekursive kopieringsfunksjoner med forskjellige feil.
Jeg er overrasket over at det ikke finnes noen kanonisk løsning.
Det kalles "strukturert kloning", fungerer eksperimentelt i Node 11 og senere, og vil forhåpentligvis lande i nettlesere. Se dette svaret for mer informasjon.
Hvis du ikke bruker Date
, funksjoner, undefined
, Infinity
, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays eller andre komplekse typer i objektet ditt, er en veldig enkel one liner for å klone et objekt dypt:
JSON.parse(JSON.stringify(objekt))
const a = {
string: 'string',
number: 123,
bool: false,
nul: null,
date: new Date(), // stringified
undef: undefined, // lost
inf: Infinity, // forced to 'null'
re: /.*/, // lost
}
console.log(a);
console.log(typeof a.date); // Date object
const clone = JSON.parse(JSON.stringify(a));
console.log(clone);
console.log(typeof clone.date); // result of .toISOString()
Se Corbans svar for referanseverdier.
Siden kloning av objekter ikke er trivielt (komplekse typer, sirkulære referanser, funksjon osv.), har de fleste større biblioteker funksjoner for å klone objekter. Ikke finn opp hjulet på nytt - hvis du allerede bruker et bibliotek, sjekk om det har en funksjon for kloning av objekter. For eksempel,
cloneDeep
; kan importeres separat via modulen lodash.clonedeep og er sannsynligvis det beste valget hvis du ikke allerede bruker et bibliotek som gir en dyp kloningsfunksjon.angular.copy
jQuery.extend(true, { }, oldObject)
; .clone()
bare kloner DOM-elementerFor fullstendighetens skyld, merk at ES6 tilbyr to grunne kopieringsmekanismer: Object.assign()
og spread operator.
Hvis det ikke fantes noen innebygd, kunne du prøve:
function clone(obj) {
if (obj === null || typeof (obj) !== 'object' || 'isActiveClone' in obj)
return obj;
if (obj instanceof Date)
var temp = new obj.constructor(); //or new Date(obj);
else
var temp = obj.constructor();
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
obj['isActiveClone'] = null;
temp[key] = clone(obj[key]);
delete obj['isActiveClone'];
}
}
return temp;
}