Ich versuche, eine Deep Copy Map-Methode für mein Redux-Projekt zu erstellen, die eher mit Objekten als mit Arrays funktioniert. Ich habe gelesen, dass in Redux jeder Zustand nichts an den vorherigen Zuständen ändern sollte.
export const mapCopy = (object, callback) => {
return Object.keys(object).reduce(function (output, key) {
output[key] = callback.call(this, {...object[key]});
return output;
}, {});
}
Es klappt:
return mapCopy(state, e => {
if (e.id === action.id) {
e.title = 'new item';
}
return e;
})
Da innere Elemente jedoch nicht tief kopiert werden, muss ich Folgendes anpassen:
export const mapCopy = (object, callback) => {
return Object.keys(object).reduce(function (output, key) {
let newObject = {...object[key]};
newObject.style = {...newObject.style};
newObject.data = {...newObject.data};
output[key] = callback.call(this, newObject);
return output;
}, {});
}
Dies ist weniger elegant, da bekannt sein muss, welche Objekte übergeben werden. Gibt es in ES6 eine Möglichkeit, die Spread-Syntax zum tiefen Kopieren eines Objekts zu verwenden?
combineReducers
die beiden (oder mehr) zusammensetzen. Wenn Sie idiomatische Redux-Techniken verwenden, verschwindet Ihr Problem des tiefen Klonens von Objekten.Antworten:
In ES6 ist keine solche Funktionalität integriert. Ich denke, Sie haben ein paar Möglichkeiten, je nachdem, was Sie tun möchten.
Wenn Sie wirklich tief kopieren möchten:
cloneDeep
Methode.Alternative Lösung für Ihr spezifisches Problem (keine tiefe Kopie)
Ich denke jedoch, wenn Sie bereit sind, ein paar Dinge zu ändern, können Sie sich etwas Arbeit sparen. Ich gehe davon aus, dass Sie alle Anrufstellen für Ihre Funktion steuern.
Geben Sie an, dass alle an übergebenen Rückrufe
mapCopy
neue Objekte zurückgeben müssen, anstatt das vorhandene Objekt zu mutieren. Beispielsweise:Dies wird verwendet
Object.assign
, um ein neues Objekt zu erstellen, Eigenschaften füre
dieses neue Objekt festzulegen und dann einen neuen Titel für dieses neue Objekt festzulegen. Dies bedeutet, dass Sie vorhandene Objekte niemals mutieren und nur bei Bedarf neue erstellen.mapCopy
kann jetzt ganz einfach sein:Vertraut im Wesentlichen darauf, dass
mapCopy
seine Anrufer das Richtige tun. Aus diesem Grund habe ich vorausgesetzt, dass Sie alle Anrufstellen kontrollieren.quelle
Verwenden Sie dies stattdessen für eine tiefe Kopie
quelle
Von MDN
Persönlich schlage ich vor, zu verwenden die cloneDeep- Funktion von Lodash für das mehrstufige Klonen von Objekten / Arrays zu verwenden.
Hier ist ein Arbeitsbeispiel:
quelle
Run code snippet
Er sollte ordnungsgemäß ausgeführt werden.Ich benutze dies oft:
quelle
Verwenden
JSON.stringify
undJSON.parse
ist der beste Weg. Denn mit dem Spread-Operator erhalten wir keine effiziente Antwort, wenn das json-Objekt ein anderes Objekt enthält. das müssen wir manuell spezifizieren.quelle
quelle
quelle
quelle
Ich selbst bin letzten Tag auf diese Antworten gestoßen und habe versucht, komplexe Strukturen, die rekursive Links enthalten können, tief zu kopieren. Da ich mit den Vorschlägen noch nicht zufrieden war, habe ich dieses Rad selbst implementiert. Und es funktioniert ganz gut. Hoffe es hilft jemandem.
Anwendungsbeispiel:
Unter https://github.com/latitov/JS_DeepCopy finden Sie Live-Beispiele zur Verwendung. Außerdem ist deep_print () vorhanden.
Wenn Sie es schnell brauchen, finden Sie hier die Quelle der Funktion deep_copy ():
Prost@!
quelle
Hier ist mein Deep-Copy-Algorithmus.
quelle
Hier ist die deepClone-Funktion, die alle primitiven, Array-, Objekt- und Funktionsdatentypen verarbeitet
quelle