Hallo ebody,
warum elementNum sich nicht ändert, hat Dedlfix erklärt. Ich möchte nur ergänzen: elementNum ist ein blöder Name. "Anzahl" ist eher Count, nicht "Number". Nenn das Property elementCount.
Aber brauchst Du dieses Property überhaupt? Das Array ist als Eigenschaft verfügbar und sein length Property lässt sich jederzeit abfragen.
Die slice-Methode ist eine Möglichkeit, ein Array zu kopieren. Das neue Array ist genau so lang und enthält die gleichen Werte wie die Kopierquelle. Die Alternative in neueren Browern ist der Spread-Operator:
let original = [1, 2, 3];
let kopie = [... original];
Das ist nicht ganz das gleiche, sofern Arrayindizes übersprungen wurden, aber in einem normalen Array mit dicht liegenden Indizes schon.
Diesen Kopiervorgang muss man aber genauer betrachten. Wenn das Array Werte eines primitiven Typs enthält, werden die Werte echt gedoppelt. Mit Ausnahme von String. Strings werden bei einer Zuweisung nicht gedoppelt - ein String besteht aus einer String-Information (wo im Speicher, wie lang) und der eigentlichen Zeichenkette. Gedoppelt wird nur die String-Information, die Zeichenkette teilen sich die beiden. Das ist unproblematisch, weil Strings in JavaScript unveränderlich sind. Ich weise auch nur deshalb darauf hin, weil man meinen könnte, das Doppeln eines Arrays mit 100 Einträgen aus String der Länge 10000 wäre eine teure Operation für Laufzeit und Speicher. Ist sie nicht, es ist genauso teuer wie das Doppeln jedes anderen Arrays.
Enthält das Array ein Objekt, wird nur die Objektreferenz gedoppelt. D.h. die Kopie und das Original zeigen danach auf das gleiche Objekt. Wenn man das nicht will, braucht man einen deep clone Algorithmus, der auch die referenzierten Objekte doppelt - und zwar rekursiv, denn die können ja auch wieder auf Objekte zeigen. Das ist nicht trivial - solche Verweisketten können geschlossen sein und das würde eine Endlosrekursion hervorrufen.
Von der Architektur her solltest du aber das datasets-Array nicht direkt manipulieren. Wenn die Datasets-Klasse dieses Array speichert, dann sollte es ihr auch gehören und von außen nicht manipuliert werden. Schreibe Methoden, die diese Manipulationen durchführen.
In neueren Browsern kannst Du auch dafür sorgen, dass Eigenschaften eines Objekts privat sind:
class Dataset {
#originalValues;
#currentValues;
constructor(values) {
this.#originalValues = values;
this.#currentValues = [...values];
}
get originalCount() { return this.#originalValues.length; }
get count() { return this.#currentValues.length; }
}
let d = new Dataset([1,2,3]);
d.#currentValues.splice(1,1); // ERROR
Ob es richtig oder falsch ist, sowohl Original als auch Modifikation zu speichern, hängt von dem Zweck der Klasse ab. Gibt es Operationen, die beide Versionen benötigen? Gibt es mehrere Datasets, alle mit ihren eigenen Originalen?
Im System.Data Namespace von Microsoft.net gibt es die Komponente ADO.NET (Active Data Objects). Die hat eine DataTable Klasse, die deinem Dataset entspricht. Eine DataTable ist ein Array aus DataRows. In jeder DataRow wird gespeichert, ob sie gelöscht, modifiziert oder neu hinzugefügt wurde. Eine Original-Row, die modifiziert wird, existiert nachher zweimal: im Original und die modifizierte Fassung. Das führt dann dazu, dass die ADO.NET Komponente ("Active Data Objects") aus einer modifizierten Datatable automagisch die SQL Statements generieren kann, die nötig sind, um die Änderungen in die Datenbank zurückzuschreiben. Willst Du sowas tun?
Rolf
sumpsi - posui - obstruxi