5167 Stimmen

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

Was ist der effizienteste Weg, um ein JavaScript-Objekt zu klonen? Ich habe gesehen obj = eval(uneval(o)); verwendet werden, sondern das nicht dem Standard entspricht und nur von Firefox unterstützt wird .

Ich habe Dinge getan wie obj = JSON.parse(JSON.stringify(o)); stellen aber die Effizienz in Frage.

Ich habe auch rekursive Kopierfunktionen mit verschiedenen Fehlern gesehen.
Ich bin überrascht, dass es keine kanonische Lösung gibt.

566 Stimmen

Eval ist nicht böse. Schlechtes Benutzen von Eval schon. Wenn Sie Angst vor seinen Nebenwirkungen haben, verwenden Sie es falsch. Die Nebenwirkungen, die Sie fürchten, sind der Grund, warum Sie es verwenden. Hat eigentlich irgendjemand Ihre Frage beantwortet?

15 Stimmen

Das Klonen von Objekten ist eine knifflige Angelegenheit, insbesondere bei benutzerdefinierten Objekten beliebiger Sammlungen. Wahrscheinlich gibt es deshalb keine fertige Methode, dies zu tun.

12 Stimmen

eval() ist im Allgemeinen eine schlechte Idee, weil viele Javascript-Engine-Optimierer abschalten müssen, wenn sie mit Variablen arbeiten, die über eval . Nur mit eval() in Ihrem Code kann zu einer schlechteren Leistung führen.

83voto

Alireza Punkte 92209

Klonen eines Objekts war immer ein Anliegen in JS, aber es war alles über vor ES6, ich Liste verschiedene Möglichkeiten zum Kopieren eines Objekts in JavaScript unten, stellen Sie sich vor, Sie haben das Objekt unten und möchte eine tiefe Kopie davon haben:

var obj = {a:1, b:2, c:3, d:4};

Es gibt nur wenige Möglichkeiten, dieses Objekt zu kopieren, ohne den Ursprung zu verändern:

  1. ES5+, Verwendung einer einfachen Funktion, um die Kopie für Sie zu erledigen:

    function deepCopyObj(obj) {
        if (null == obj || "object" != typeof obj) return obj;
        if (obj instanceof Date) {
            var copy = new Date();
            copy.setTime(obj.getTime());
            return copy;
        }
        if (obj instanceof Array) {
            var copy = [];
            for (var i = 0, len = obj.length; i < len; i++) {
                copy[i] = deepCopyObj(obj[i]);
            }
            return copy;
        }
        if (obj instanceof Object) {
            var copy = {};
            for (var attr in obj) {
                if (obj.hasOwnProperty(attr)) copy[attr] = deepCopyObj(obj[attr]);
            }
            return copy;
        }
        throw new Error("Unable to copy obj this object.");
    }
  2. ES5+, unter Verwendung von JSON.parse y JSON.stringify .

    var deepCopyObj = JSON.parse(JSON.stringify(obj));
  3. Winklig:

    var deepCopyObj = angular.copy(obj);
  4. jQuery:

    var deepCopyObj = jQuery.extend(true, {}, obj);
  5. Underscore.js & Lodash:

    var deepCopyObj = _.cloneDeep(obj); //latest version of Underscore.js makes shallow copy

Ich hoffe, das hilft

72voto

Zibri Punkte 7918
var clone = function() {
    var newObj = (this instanceof Array) ? [] : {};
    for (var i in this) {
        if (this[i] && typeof this[i] == "object") {
            newObj[i] = this[i].clone();
        }
        else
        {
            newObj[i] = this[i];
        }
    }
    return newObj;
}; 

Object.defineProperty( Object.prototype, "clone", {value: clone, enumerable: false});

67voto

pvorb Punkte 6786

Es gibt eine Bibliothek (genannt "clone") das dies sehr gut tut. Es bietet das vollständigste rekursive Klonen/Kopieren beliebiger Objekte, das ich kenne. Es unterstützt auch zirkuläre Referenzen, was von den anderen Antworten noch nicht abgedeckt wird.

Sie können zu finden auf npm auch. Es kann sowohl für den Browser als auch für Node.js verwendet werden.

Hier ist ein Beispiel für die Verwendung:

Installieren Sie es mit

npm install clone

oder verpacken Sie es mit Ender .

ender build clone [...]

Sie können den Quellcode auch manuell herunterladen.

Dann können Sie es in Ihrem Quellcode verwenden.

var clone = require('clone');

var a = { foo: { bar: 'baz' } };  // inital value of a
var b = clone(a);                 // clone a -> b
a.foo.bar = 'foo';                // change a

console.log(a);                   // { foo: { bar: 'foo' } }
console.log(b);                   // { foo: { bar: 'baz' } }

(Haftungsausschluss: Ich bin der Autor der Bibliothek.)

57voto

Joe Punkte 187

Ich weiß, dass dies ein alter Beitrag ist, aber ich dachte, dass er vielleicht für die nächste Person, die darüber stolpert, hilfreich ist.

Solange Sie einem Objekt nichts zuweisen, behält es keinen Verweis im Speicher. Um also ein Objekt zu erstellen, das Sie mit anderen Objekten teilen möchten, müssen Sie eine Fabrik wie folgt erstellen:

var a = function(){
    return {
        father:'zacharias'
    };
},
b = a(),
c = a();
c.father = 'johndoe';
alert(b.father);

50voto

itsadok Punkte 27963

Wenn Sie es verwenden, wird die Underscore.js Bibliothek hat eine klonen. Methode.

var newObject = _.clone(oldObject);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X