Dies scheint eine sehr einfache und effektive tiefe Kopie zu sein! Warum ist das nicht höher? Stimmt etwas mit dieser Antwort nicht?
TSG
Für eine Deep-Copy-Lösung, bei der alle Verweise entfernt werden, ist dies die beste Methode, die in Browser / CommonJS usw. verfügbar ist. Ich verwende sie in der Produktion, wenn ein Objekt-Snapshot benötigt wird. Ich schätze, ich bin angekommen, um etwas spät zu antworten, wie 1 Jahr zu spät. @ TSG
Gabriel Balsa Cantú
2
Wenn Sie ein Objektliteral mit Funktionen verwenden (nicht nur Werte), werden diese weggelassen, aber Sie können sie leicht kombinieren. Object.assing({}, oldObject, JSON.parse(JSON.stringify(oldObject)))Dadurch werden Ihre Funktionseigenschaften aus Ihrem Objektliteral neu gefüllt und mit JSON wird eine tiefe Kopie ohne erstellt jede Beziehung zum Original.
Gabriel Balsa Cantú
Beste Antwort meiner Meinung nach
Johannes Wanzek
3
Beachten Sie jedoch, dass dies bei einigen Daten nicht funktioniert.
Die gängigsten Bibliotheken verfügen über Typisierungs- CLI-Tools, sodass Sie auch beim Transpilieren von TypeScript nahtlos alles verwenden können, was Sie möchten.
Object.assign () kopiert nicht tief, wenn sich verschachtelte Objekte im Zielobjekt befinden. Als naive Lösung können Sie das Zielobjekt durchgehen und Object.assign () für jede Eigenschaft des Objekts ausführen! Es hat bei mir funktioniert, als ich nicht von einer Drittanbieter-Bibliothek abhängig sein wollte
Dany Wehbe
21
Eine andere Möglichkeit besteht darin, eine eigene Funktion zu implementieren:
/**
* Returns a deep copy of the object
*/publicstaticdeepCopy(oldObj: any) {
var newObj = oldObj;
if (oldObj && typeof oldObj === "object") {
if (oldObj instanceofDate) {
returnnewDate(oldObj.getTime());
}
newObj = Object.prototype.toString.call(oldObj) === "[object Array]" ? [] : {};
for (var i in oldObj) {
newObj[i] = this.deepCopy(oldObj[i]);
}
}
return newObj;
}
Das Kopieren nach Wert hat bei mir mit Lodash nicht funktioniert. Weißt du vielleicht warum? Ich erhalte immer noch referenzierte Werte, daher ändern sich beide gleichzeitig, wenn ich einen ändere.
Vladimir Despotovic
5
Create helper class with name deepCopy.ts
/*
* DeepCopy class helps to copy an Original Array or an Object without impacting on original data
*/
export class DeepCopy {
static copy(data: any) {
let node;
if (Array.isArray(data)) {
node = data.length > 0 ? data.slice(0) : [];
node.forEach((e, i) => {
if (
(typeof e === 'object' && e !== {}) ||
(Array.isArray(e) && e.length > 0)
) {
node[i] = DeepCopy.copy(e);
}
});
} else if (data && typeof data === 'object') {
node = data instanceof Date ? data : Object.assign({}, data);
Object.keys(node).forEach((key) => {
if (
(typeof node[key] === 'object' && node[key] !== {}) ||
(Array.isArray(node[key]) && node[key].length > 0)
) {
node[key] = DeepCopy.copy(node[key]);
}
});
} else {
node = data;
}
return node;
}
}
Importieren Sie die deepCopy-Datei, wo immer Sie sie benötigen, und verwenden Sie den folgenden Code:
DeepCopy.copy (arg); Hier würde arg entweder Objekt oder Array, das Sie wollen
Dies ist eigentlich die beste Antwort. Es kopiert Daten effektiv tief, ohne externe Bibliotheken zu importieren. Ich möchte nicht eine ganze Bibliothek einbinden, um nur eine Funktion zu verwenden (auch wenn es nur 18 KB sind).
Frozenfrank
1
Wenn die Quelle ein Array von Objekten ist , verwenden Sie map:
let cloned = source.map(x => Object.assign({}, x));
export class DeepCopy {
static copy(data: any, objMap?: WeakMap<any, any>) {
if (!objMap) {
// Map for handle recursive objects
objMap = new WeakMap();
}
// recursion wrapper
const deeper = value => {
if (value && typeof value === 'object') {
return DeepCopy.copy(value, objMap);
}
return value;
};
// Array value
if (Array.isArray(data)) return data.map(deeper);
// Object value
if (data && typeof data === 'object') {
// Same object seen earlier
if (objMap.has(data)) return objMap.get(data);
// Date object
if (data instanceof Date) {
const result = new Date(data.valueOf());
objMap.set(data, result);
return result;
}
// Use original prototype
const node = Object.create(Object.getPrototypeOf(data));
// Save object to map before recursion
objMap.set(data, node);
for (const [key, value] of Object.entries(data)) {
node[key] = deeper(value);
}
return node;
}
// Scalar value
return data;
}
}
Ich stehe vor dem Problem des tiefen Kopierens. angular.copy ({}, factory) und angular.extend ({}, factory) eignen sich gut für Array- oder Hashing-Objekte. Beim Kopieren eines Objekts in einen Calass kann es jedoch manchmal zu Problemen mit verbundenen Abhängigkeiten kommen. Ich habe dieses Problem so gelöst:
Ich habe eine sehr einfache Funktion in Typoskript erstellt, die alle möglichen Eingaben akzeptiert und die tief geklonte Kopie dieses Objekts liefert.
Hoffe es wird jemandem helfen.
public deepCopy(obj) {
var clonedObject: any;
if (obj instanceof Array) {
var itemArray = Object.assign([], obj);
clonedObject = itemArray;
for (var j = 0; j < clonedObject.length; j++) {
clonedObject[j] = this.deepCopy(clonedObject[j]);
}
return clonedObject;
}
else if (typeof obj === 'number' || typeof obj == 'string') {
return obj
}
else {
var item = Object.assign({}, obj);
clonedObject = item;
let allKeys = Object.keys(clonedObject);
for (var i = 0; i < allKeys.length; i++) {
if (clonedObject[allKeys[i]] instanceof Array) {
//If the calue is Array
clonedObject[allKeys[i]] = this.deepCopy(clonedObject[allKeys[i]]);
}
else if (clonedObject[allKeys[i]] instanceof Date) {
clonedObject[allKeys[i]] = new Date(clonedObject[allKeys[i]].valueOf());
}
else if (clonedObject[allKeys[i]] instanceof Object){
//if the value is JOBJECT.
clonedObject[allKeys[i]] = this.deepCopy(clonedObject[allKeys[i]]);
}
}
return clonedObject;
}
}
Duplicate
vielleicht, aber ich wollte einenon-polyfill
Lösung. genau wieangular.copy()
angular.copy()
hmm. Soll ich die Frage löschen?Antworten:
Sie können auch verwenden:
JSON.parse(JSON.stringify(Object))
Wenn es sich in Ihrem Bereich befindet, befindet es sich in jeder Angular-Komponente, Direktive usw. und auch in jeder Knotenumgebung.
Sofern Sie keine Zirkelreferenz haben, sollte diese funktionieren und Ihre Variablenreferenz effektiv vom ursprünglichen Objekt trennen.
quelle
Object.assing({}, oldObject, JSON.parse(JSON.stringify(oldObject)))
Dadurch werden Ihre Funktionseigenschaften aus Ihrem Objektliteral neu gefüllt und mit JSON wird eine tiefe Kopie ohne erstellt jede Beziehung zum Original.Diese Frage ist kein Duplikat von Wie kann ich angle.copy in Angular 2 verwenden, da das OP nach tiefen Kopierobjekten fragt ? In der verknüpften Antwort wird Object.assign () empfohlen, das keine tiefe Kopie erstellt.
Die Verwendung von Angular2 hindert Sie nicht daran, andere Bibliotheken wie jQuery zum tiefen Kopieren von Objekten mit ihrer Funktion $ .clone () oder lodash mit _.cloneDeep () zu verwenden .
Die gängigsten Bibliotheken verfügen über Typisierungs- CLI-Tools, sodass Sie auch beim Transpilieren von TypeScript nahtlos alles verwenden können, was Sie möchten.
Siehe auch: Was ist der effizienteste Weg, um ein Objekt in JavaScript tief zu klonen?
quelle
Eine andere Möglichkeit besteht darin, eine eigene Funktion zu implementieren:
/** * Returns a deep copy of the object */ public static deepCopy(oldObj: any) { var newObj = oldObj; if (oldObj && typeof oldObj === "object") { if (oldObj instanceof Date) { return new Date(oldObj.getTime()); } newObj = Object.prototype.toString.call(oldObj) === "[object Array]" ? [] : {}; for (var i in oldObj) { newObj[i] = this.deepCopy(oldObj[i]); } } return newObj; }
quelle
Sie können
deep copy
ein Objekt in Angular mit der cloneDeep-Methode von lodash erstellen:Installieren Sie lodash mit
yarn add lodash
odernpm install lodash
.Importieren
cloneDeep
und verwenden Sie es in Ihrer Komponente :Es sind nur 18 KB zu Ihrem Build hinzugefügt, was sich für die Vorteile lohnt.
Ich habe hier auch einen Artikel geschrieben , wenn Sie mehr darüber erfahren möchten, warum Sie lodashs cloneDeep verwenden.
quelle
Importieren Sie die deepCopy-Datei, wo immer Sie sie benötigen, und verwenden Sie den folgenden Code: DeepCopy.copy (arg); Hier würde arg entweder Objekt oder Array, das Sie wollen
quelle
Wenn die Quelle ein Array von Objekten ist , verwenden Sie map:
ODER
quelle
Einige Modifikationen für KrishnamrajuKs Antwort
quelle
Ich stehe vor dem Problem des tiefen Kopierens. angular.copy ({}, factory) und angular.extend ({}, factory) eignen sich gut für Array- oder Hashing-Objekte. Beim Kopieren eines Objekts in einen Calass kann es jedoch manchmal zu Problemen mit verbundenen Abhängigkeiten kommen. Ich habe dieses Problem so gelöst:
quelle
Ich habe eine sehr einfache Funktion in Typoskript erstellt, die alle möglichen Eingaben akzeptiert und die tief geklonte Kopie dieses Objekts liefert.
Hoffe es wird jemandem helfen.
quelle