JS: Erstellt Object.assign() eine tiefe Kopie oder eine flache Kopie?

Lesezeit: 4 Minuten

Ich bin gerade auf dieses Konzept gestoßen

var copy = Object.assign({}, originalObject);

wodurch eine Kopie des Originalobjekts in das “copy” Objekt. Meine Frage ist jedoch, erstellt diese Art des Klonens von Objekten eine tiefe Kopie oder eine flache Kopie?

PS: Die Verwirrung ist, wenn es eine tiefe Kopie erstellt, wäre es der einfachste Weg, ein Objekt zu klonen.

  • doc ist selbsterklärend, denke ich: “Die Methode Object.assign() wird verwendet, um die Werte von all aufzählbare eigene Eigenschaften von einem oder mehreren Quellobjekten zu einem Zielobjekt”

    – Sebas

    29. Dezember 15 um 5:05 Uhr


  • Lodashs _.clonedeep erstellt eine tiefe Kopie und funktioniert wie erwartet lodash.com/docs/4.17.11#cloneDeep

    – Christoph Tokar

    7. November 18 um 8:23 Uhr


JS Erstellt Objectassign eine tiefe Kopie oder eine flache Kopie
Ramanlfc

Vergessen Sie tiefe Kopien, selbst flache Kopien sind nicht sicher, wenn das Objekt, das Sie kopieren, eine Eigenschaft hat enumerable Attribut auf false gesetzt.

MDN:

Die Methode Object.assign() kopiert nur aufzählbare und eigene Eigenschaften von einem Quellobjekt in ein Zielobjekt

Nehmen Sie dieses Beispiel

var o = {};

Object.defineProperty(o,'x',{enumerable: false,value : 15});

var ob={}; 
Object.assign(ob,o);

console.log(o.x); // 15
console.log(ob.x); // undefined

  • Das beantwortet die Frage nicht ganz. Vielmehr sagt es, was passieren wird, wenn es nicht aufzählbar ist.

    – Emobe

    15. Juni 20 um 8:49 Uhr

Durch die Nutzung Object.assign()machst du eigentlich Flache Kopie Ihres Objekts. Immer wenn wir eine Operation wie das Zuweisen eines Objekts zu einem anderen ausführen, führen wir tatsächlich eine flache Kopie durch, dh wenn OBJ1 ein Objekt ist, wird die Änderung durch ein anderes Objekt, das OBJ2 ist, auch Änderungen in OBJ1 widerspiegeln.

  • Wenn es nur eine flache Kopie erstellt, wie funktioniert Redux? Ich dachte, der springende Punkt wäre, eine tiefe Kopie der Daten zu erstellen, die gesendet werden, damit sich bei einer Änderung der Daten außerhalb des Geschäfts nicht auch das ändert, was sich im Geschäft befindet. Wenn es sich um eine flache Kopie handeln würde, würden die Daten verknüpft, was zu Problemen mit den Daten führt, die den Inhalt des Geschäfts ändern, auch ohne Versand, richtig?

    – Stackjlei

    15. September 16 um 23:35 Uhr

  • Ich bin in Redux auf dasselbe Problem gestoßen und bin schließlich zu JSON.parse (JSON.stringify()) gegangen. Dies hat auch Probleme, wenn das Objekt von einem anderen Paket mutiert wird und rekursive Probleme verursacht. Ich suche nach einer besseren Alternative. Diese Methode ist immer noch die, die ich verwende.

    – Stu

    5. Februar 18 um 19:17 Uhr

Es erstellt eine flache Kopie, entsprechend dieser Absatz von MDN:

Für Deep Cloning müssen wir andere Alternativen verwenden, da Object.assign() Eigenschaftswerte kopiert. Wenn der Quellwert eine Referenz auf ein Objekt ist, wird nur dieser Referenzwert kopiert.

Für Redux-Zwecke Object.assign() ist ausreichend, da der Status einer Redux-App nur unveränderliche Werte (JSON) enthält.

  • Könnte der Redux-Zustand einer App keine Objekte mit Verweisen auf andere Objekte enthalten?

    – Victor Zamanian

    15. August 17 um 10:47 Uhr

  • @VictorZamanian Das kann es definitiv, daher ist Object.assign je nach Datenstruktur möglicherweise nicht das richtige Werkzeug. ich finde Unveränderlichkeitshelfer besonders nützlich für Redux-Zustände. Es führt nur eine tiefe Kopie dessen aus, was Sie ändern, und verwendet flache Kopien für alles andere.

    – Burak

    3. Mai 18 um 13:28 Uhr

Für klein Data structures Ich sehe das JSON.stringify() und JSON.parse() schön arbeiten.

// store as JSON
var copyOfWindowLocation = JSON.stringify(window.location)
console.log("JSON structure - copy:", copyOfWindowLocation)
// convert back to Javascript Object
copyOfWindowLocation = JSON.parse(copyOfWindowLocation)
console.log("Javascript structure - copy:", copyOfWindowLocation)

Andere Antworten sind kompliziert.
Manche beantworten die Frage gar nicht.

Unten hat bei mir funktioniert

// orignal object with deep keys
var originalObject = {
    k1: "v1",
    k2: "v2",
    deepObj: {
        k3: "v3",
        k4: "v4"
    }
};

// make copies now
var copy1 = JSON.parse(JSON.stringify(originalObject));
var copy2 = JSON.parse(JSON.stringify(originalObject));

Hoffentlich hilft das.

JS Erstellt Objectassign eine tiefe Kopie oder eine flache Kopie
Terrymorse

Wie oben erwähnt, Object.assign() führt einen flachen Klon aus, kopiert die benutzerdefinierten Methoden des Quellobjekts nicht und kopiert keine Eigenschaften mit enumerable: false.

Das Beibehalten von Methoden und nicht aufzählbaren Eigenschaften erfordert mehr Code, aber nicht viel mehr.

Dadurch wird ein flacher Klon eines Arrays oder Objekts erstellt, wobei die Methoden und alle Eigenschaften der Quelle kopiert werden:

function shallowClone(src) {
  let dest = (src instanceof Array) ? [] : {};

// duplicate prototypes of the source
  Object.setPrototypeOf(dest, Object.getPrototypeOf(src));

  Object.getOwnPropertyNames(src).forEach(name => {
    const descriptor = Object.getOwnPropertyDescriptor(src, name);
    Object.defineProperty(dest, name, descriptor);
  });
  return dest;
}

Beispiel:

class Custom extends Object {
  myCustom() {}
}

const source = new Custom();
source.foo = "this is foo";
Object.defineProperty(source, "nonEnum", {
  value: "do not enumerate",
  enumerable: false
});
Object.defineProperty(source, "nonWrite", {
  value: "do not write",
  writable: false
});
Object.defineProperty(source, "nonConfig", {
  value: "do not config",
  configurable: false
});

let clone = shallowClone(source);

console.log("source.nonEnum:",source.nonEnum);
// source.nonEnum: "do not enumerate"
console.log("clone.nonEnum:", clone.nonEnum);
// clone.nonEnum: – "do not enumerate"

console.log("typeof source.myCustom:", typeof source.myCustom);
// typeof source.myCustom: – "function"
console.log("typeof clone.myCustom:", typeof clone.myCustom);
// typeof clone.myCustom: – "function"

jsfiddle

1644258966 98 JS Erstellt Objectassign eine tiefe Kopie oder eine flache Kopie
Saqib Naseeb

var copy = Object.assign({}, originalObject);

Eine flache Kopie, die die Kopie ändert, spiegelt auch Änderungen in Ihrem ursprünglichen Objekt wider. Um also eine tiefe Kopie durchzuführen, würde ich die empfehlen lodash KlonDeep

import cloneDeep from 'lodash/cloneDeep';
var copy = cloneDeep(originalObject);

  • Ist Loadash nicht veraltet? Ich habe einige Blogs darüber gelesen, dass es nach ES6 veraltet ist

    – Zortext

    15. Oktober 21 um 9:07 Uhr

.

813110cookie-checkJS: Erstellt Object.assign() eine tiefe Kopie oder eine flache Kopie?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy