381 Stimmen

Typescript - Objekt klonen

Ich habe eine Superklasse, die das Elternelement (Entity) für viele Unterklassen (Customer, Product, ProductCategory...) ist

Ich möchte in Typescript dynamisch ein Objekt klonen, das verschiedene Teilobjekte enthält.

Zum Beispiel: ein Customer, der verschiedene Product enthält, die eine ProductCategory haben

var cust:Customer = new Customer();

cust.name = "someName";
cust.products.push(new Product(someId1));
cust.products.push(new Product(someId2));

Um den gesamten Objektbaum zu klonen, habe ich eine Funktion in Entity erstellt

public clone():any {
    var cloneObj = new this.constructor();
    for (var attribut in this) {
        if(typeof this[attribut] === "object"){
           cloneObj[attribut] = this.clone();
        } else {
           cloneObj[attribut] = this[attribut];
        }
    }
    return cloneObj;
}

Der new Fehler tritt auf, wenn er zu Javascript transpiliert wird: Fehler TS2351: Kann 'new' nicht mit einem Ausdruck verwenden, dessen Typ über eine Aufruf- oder Konstruktions-Signatur verfügt.

Obwohl das Skript funktioniert, möchte ich den transpilierten Fehler loswerden

0voto

user1931270 Punkte 65

Ich verwende das Folgende beim Klonen. Es behandelt fast alles, was ich brauche, und kopiert sogar die Funktionen in das neu erstellte Objekt.

  public static clone(value: any) : T {
    var o: any = JSON.parse(JSON.stringify(value));
    var functions = (Object.getOwnPropertyNames(Object.getPrototypeOf(value))).filter(a => a != 'constructor');
    for (var i = 0; i < functions.length; i++) {
      var name = functions[i].toString();
      o[name] = value[name];
    }
    return o;
  }

0voto

GapTheMind Punkte 1

Ich habe den Algorithmus von @marckassay genommen und ihn für Arrays angepasst und so dass ein Array auf oberster Ebene steht:

function deepClone(source: T): any {
  if (Array.isArray(source)) {
    let res = [];
    for (let ii of source as any[]) {
      res.push(deepClone(ii));
    }
    return res;
  } else if (typeof source === 'object') {
    let results: { [k: string | number]: any } = {};
    for (let P in source) {
      results[P] = deepClone(source[P]);
    }
    return results;
  } else {
    return source;
  }
};

-1voto

Ferhatos Punkte 73

Für einen einfachen Klon des gesamten Inhalts des Objekts, stringifye ich einfach die Instanz und parse sie dann:

let cloneObject = JSON.parse(JSON.stringify(objectToClone))

Wenn ich Daten im objectToClone-Baum ändere, gibt es keine Änderung in cloneObject. Das war meine Anforderung.

Hoffentlich hilft es

-2voto

LosManos Punkte 6702

Wenn Sie das Zielobjekt bereits haben und es nicht neu erstellen möchten (z. B. beim Aktualisieren eines Arrays), müssen Sie die Eigenschaften kopieren.
Wenn Sie es so gemacht haben:

Object.keys(source).forEach((key) => {
    copy[key] = source[key]
})

Lob gebührt. (schauen Sie sich die Überschrift "Version 2" an)

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