Was ist der effizienteste Weg, ein Objekt in JavaScript zu klonen?

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.

Lösung

Natives tiefes Klonen

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.

Schnelles Klonen mit Datenverlust - JSON.parse/stringify

Wenn Sie keine Dates, 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.

Zuverlässiges Klonen mit einer Bibliothek

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,

ES6

Der Vollständigkeit halber sei angemerkt, dass ES6 zwei flache Kopiermechanismen anbietet: Object.assign() und den spread operator.

Kommentare (24)

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;
}
Kommentare (11)
function clone(obj)
 { var clone = {};
   clone.prototype = obj.prototype;
   for (property in obj) clone[property] = obj[property];
   return clone;
 }
Kommentare (5)