Was ist der effizienteste Weg, um ein JavaScript-Objekt zu klonen? Ich've gesehen obj = eval(uneval(o));
verwendet werden, aber that's Nicht-Standard und nur von Firefox unterstützt.
Ich've Dinge getan wie obj = JSON.parse(JSON.stringify(o));
, stelle aber die Effizienz in Frage.
Ich'habe auch rekursive Kopierfunktionen mit verschiedenen Fehlern gesehen.
Ich bin überrascht, dass es keine kanonische Lösung gibt.
Es heißt "strukturiertes Klonen", funktioniert experimentell in Node 11 und später und wird hoffentlich in Browsern landen. Siehe [diese Antwort] (https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/10916838#10916838) für weitere Details.
Wenn Sie keine Date
s, Funktionen, undefined
, Infinity
, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays oder andere komplexe Typen in Ihrem Objekt verwenden, ist ein sehr einfacher One-Liner, um ein Objekt tief zu klonen:
JSON.parse(JSON.stringify(object))
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()
Siehe [Corbans Antwort] (https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/5344074#5344074) für Benchmarks.
Da das Klonen von Objekten nicht trivial ist (komplexe Typen, zirkuläre Referenzen, Funktionen usw.), bieten die meisten großen Bibliotheken Funktionen zum Klonen von Objekten. Erfinden Sie das Rad nicht neu - wenn Sie bereits eine Bibliothek verwenden, prüfen Sie, ob sie eine Funktion zum Klonen von Objekten enthält. Zum Beispiel,
cloneDeep
; kann separat über das Modul lodash.clonedeep importiert werden und ist wahrscheinlich die beste Wahl, wenn Sie nicht bereits eine Bibliothek verwenden, die eine Funktion zum tiefen Klonen bietetangular.copy
jQuery.extend(true, { }, oldObject)
; .clone()
klont nur DOM-ElementeDer Vollständigkeit halber sei angemerkt, dass ES6 zwei flache Kopiermechanismen anbietet: Object.assign()
und den spread operator.
Wenn es kein eingebautes System gibt, können Sie es versuchen:
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;
}
function clone(obj)
{ var clone = {};
clone.prototype = obj.prototype;
for (property in obj) clone[property] = obj[property];
return clone;
}