huhu: Objekte klonen

Hallo,

ich suche nach einer Möglichkeit, ein bestehendes Objekt zu klonen. Damit meine ich, dass das geklonte Objekt dem Original gleicht, aber von diesem unabhängig ist, so dass Änderungen in dem einem keine Auswirkungen auf das andere haben.

Natürlich habe ich mich informiert und zwei Funktionen gefunden:

  
function clone1(o) {  
	function c(o) {  
		for (var i in o) {  
			this[i] = o[i];  
		}  
	}  
	return new c(o);  
}  
  
function clone2(obj) {  
	if(obj == null || typeof(obj) != 'object') return obj;  
	var c = new obj.constructor();  
	for(var key in obj) {  
		c[key] = clone2(obj[key]);  
	}  
	return c;  
}  

Jedoch scheinen beide nicht zu funktionieren, sie liefern zwar eine Referenz, aber kein unabhängiges Objekt.

Hier der Testcode:

  
function charakter() {  
	var charakter = this;  
	var staerke = 0;  
	var geschick = 0;  
	var vitalitaet = 0;  
	  
	charakter.attributeHinzufuegen = function (staerkeNeu,geschickNeu,vitalitaetNeu) {  
		if (isset(staerkeNeu,geschickNeu,vitalitaetNeu)) {  
			staerke = staerkeNeu;  
			geschick = geschickNeu;  
			vitalitaet = vitalitaetNeu;  
		}  
	}  
	  
	charakter.werte = function () {  
		return new Array(staerke,geschick,vitalitaet);  
	}  
}  
  
var charakter0 = new charakter();  
var charakter1 = clone1(charakter0);  
charakter0.attributeHinzufuegen(12,2,19);  
charakter1.attributeHinzufuegen(14,8,2);  
// gibt zweimal „14,8,2“ aus:  
alert(charakter0.werte());  
alert(charakter1.werte());  
  
var charakter0 = new charakter();  
var charakter1 = clone2(charakter0);  
charakter0.attributeHinzufuegen(12,2,19);  
charakter1.attributeHinzufuegen(14,8,2);  
// gibt zweimal „14,8,2“ aus:  
alert(charakter0.werte());  
alert(charakter1.werte());  

Bin Anfänger in objektorientierter Programierung, lese mich aber gerne auch in komplexere Zusammenhänge ein.
Wenn ich hier grundsätzliche Fehler gemacht habe, würde ich mich freuen, darauf hingewiesen zu werden.
Ansonsten hoffe ich auf Anregungen zum Klonen.

Alles Gute und vielen Dank

huhu

  1. hi,

    Beide funktionen die du dort verwendest erstellen zwar objecte können aber jedoch nur die public members kopieren. Wobei die obere funktion noch nicht einmal ein objekt der selben klasse zurück liefert. Der Grund warum die objekte scheinber nicht geclont wurden aber trotzdem das setzen von werten an beiden objecten möglich ist liegt daran, dass die public methoden auch felder sind und somit mit kopiert wurden und die methoden des geklonten objects immer noch auf die privaten felder des original objects zeigen. D.h. alle methoden von dein geklonten sowie von deinem original object ändern nur die felder deines original objectes. eine möglich keit währe alle felder public zu machen oder eine methode zu deklarieren die salopt gesagt die klasse genaustens kennt und alle privaten felder ausliest und einem klon wieder einflöst

    ich hoffe damit konnte ich dir erstmal weiterhelfen

    grüsse flo

    1. hi,

      Hi Flo, danke für die Antwort.

      Beide funktionen die du dort verwendest erstellen zwar objecte können aber jedoch nur die public members kopieren.

      Ah, das liegt daran, dass „for in“ nur die öffentlichen Member sieht?
      Ist das immer so, oder liegt das daran, dass die Methoden aus dem allgemeinen Kontext gestartet werden? Hätten die clone-Funktionen Zugriff auf die privaten Member, wenn ich sie dem Objekt anhänge und damit aus dem Kontext des Objekts starte? Oder ist so etwas grundsätzlich unmöglich?

      eine möglich keit währe alle felder public zu machen

      Für mich ist es kein Unterschied, ob die Felder privat oder öffentlich sind. Ich hab das nur so gemacht, weil in den Tutorien empfohlen wird, interne Objekte privat zu halten und zur Kommunikation nach außen eine öffentliche Schnittstelle anzubieten.

      ich hoffe damit konnte ich dir erstmal weiterhelfen

      grüsse flo

      Ja, sehr.

      Alles Gute

      huhu

      1. hi,

        Ah, das liegt daran, dass „for in“ nur die öffentlichen Member sieht?

        richtig weil sie ja von aussen auf das object zugreift und somit auch nur die public member sieht

        Ist das immer so, oder liegt das daran, dass die Methoden aus dem allgemeinen Kontext gestartet werden?

        nein eine methode die in der klasse definiert ist hat natürlich auch zugriff auf private member seines objectes, sie kann jedoch nicht auf andere private members von objecte der gleichen klasse zugreiffen wie java es zb. kann

        Hätten die clone-Funktionen Zugriff auf die privaten Member, wenn ich sie dem Objekt anhänge und damit aus dem Kontext des Objekts starte? Oder ist so etwas grundsätzlich unmöglich?

        Nun grundsätzlich ist es schon möglich, jedoch kann man durch die privaten members nicht iterrieren, da sie keine direkte object zugehörigkeit haben also nicht über this erreichbar sind

        Das würde bedeuten das eine clone methode erstens in der klasse definiert werden muss jedes memebr einzeln ausgelesen werden muss und dem clone im konstruktor übergeben werden muss, da man diese werte im geklonten objekt anders nicht setzen könnte, es sei dem man hat setter für die privaten felder

        Für mich ist es kein Unterschied, ob die Felder privat oder öffentlich sind. Ich hab das nur so gemacht, weil in den Tutorien empfohlen wird, interne Objekte privat zu halten und zur Kommunikation nach außen eine öffentliche Schnittstelle anzubieten.

        hm war das ein tutorial zur oop oder direkt auf jabvascript bezogen? grundsätzlich würde ich dem zustimmen doch in js muss man manchen umweg gehen um zu sein ziel zu kommen

        grüsse flo

        1. Hallo Flo,

          danke sehr für die Erklärungen.

          hm war das ein tutorial zur oop oder direkt auf jabvascript bezogen?

          Etwa hier wird darauf eingegangen: http://aktuell.de.selfhtml.org/artikel/javascript/organisation/#kapselung

          Alles Gute

          huhu

          1. Hm, vielleicht hab ich es ja doch nicht kapiert.
            Habe jetzt Variablen public gemacht, aber das Ergebnis ist immer noch das selbe. Ich hab auch mal die prototype.js ausprobiert, die bietet auch eine clone-Funktion an, aber immer noch lassen sich die beiden Objekte nach dem Klonen nicht unabhängig voneinander verändern.

            Offenbar habe ich etwas grundlegendes nicht verstanden.

            Hier ist noch mal der (veränderte) Testcode:

            function clone1(o) {  
                    function c(o) {  
                            for (var i in o) {  
                                    this[i] = o[i];  
                            }  
                    }  
                    return new c(o);  
            }  
              
            function clone2(obj) {  
                    if(obj == null || typeof(obj) != 'object') return obj;  
                    var c = new obj.constructor();  
                    for(var key in obj) {  
                            c[key] = clone2(obj[key]);  
                    }  
                    return c;  
            }  
              
            function charakter() {  
                    var charakter = this;  
                    charakter.staerke = 0;  
                    charakter.geschick = 0;  
                    charakter.vitalitaet = 0;  
              
                    charakter.attributeHinzufuegen = function (staerkeNeu,geschickNeu,vitalitaetNeu) {  
                            if (isset(staerkeNeu,geschickNeu,vitalitaetNeu)) {  
                                    charakter.staerke = staerkeNeu;  
                                    charakter.geschick = geschickNeu;  
                                    charakter.vitalitaet = vitalitaetNeu;  
                            }  
                    }  
              
                    charakter.werte = function () {  
                            return new Array(charakter.staerke,charakter.geschick,charakter.vitalitaet);  
                    }  
            }  
              
            var charakter0 = new charakter();  
            var charakter1 = clone1(charakter0);  
            charakter0.attributeHinzufuegen(12,2,19);  
            charakter1.attributeHinzufuegen(14,8,2);  
            // gibt zweimal „14,8,2“ aus:  
            alert(charakter0.werte());  
            alert(charakter1.werte());  
              
            var charakter0 = new charakter();  
            var charakter1 = clone2(charakter0);  
            charakter0.attributeHinzufuegen(12,2,19);  
            charakter1.attributeHinzufuegen(14,8,2);  
            // gibt zweimal „14,8,2“ aus:  
            alert(charakter0.werte());  
            alert(charakter1.werte());
            

            Sorry, dass ich noch mal damit nerve, vielleicht sehe ich ja auch morgen klarer.

            Alles Gute

            huhu

            1. So, ich bin jetzt einen Schritt weiter:

              Das Klonen funktioniert prinzipiell, wenn ich die Werte direkt ändere und auslese, werden sie wie gewünscht ausgegeben:

                
              charakter0.staerke = 12;  
              charakter1.staerke = 19;  
              // Gibt „12“ aus:  
              alert(charakter0.staerke);  
              // Gibt „19“ aus:  
              alert(charakter1.staerke);
              

              Also scheinen nur die Objektmethoden (in diesem Fall attributeHinzufuegen und werte) von der Seltsamkeit betroffen zu sein.

              Nun ja, ich forsche mal weiter.

              Alles Gute

              huhu

              1. Aha, ich hatte die vielen Ratschläge nicht endgültig befolgt und nur die Variablen zu public members gemacht, nicht jedoch die Funktionen.
                Diese waren über „var charakter = this;“ immer noch „privat“.

                Nun funktioniert es:

                function clone(obj) {  
                        if(obj == null || typeof(obj) != 'object') return obj;  
                        var c = new obj.constructor();  
                        for(var key in obj) {  
                                c[key] = clone(obj[key]);  
                        }  
                        return c;  
                }  
                  
                function charakter() {  
                        this.staerke = 0;  
                        this.geschick = 0;  
                        this.vitalitaet = 0;  
                  
                        this.attributeHinzufuegen = function (staerke,geschick,vitalitaet) {  
                                        this.staerke = staerke;  
                                        this.geschick = geschick;  
                                        this.vitalitaet = vitalitaet;  
                        }  
                  
                        this.werte = function () {  
                                return new Array(this.staerke,this.geschick,this.vitalitaet);  
                        }  
                }  
                  
                var charakter0 = new charakter();  
                var charakter1 = clone(charakter0);  
                charakter0.attributeHinzufuegen(12,2,19);  
                charakter1.attributeHinzufuegen(14,8,2);  
                // Juhu, gibt „12,2,19“ und „14,8,2“ aus:  
                alert(charakter0.werte());  
                alert(charakter1.werte());
                

                Ich bin ja froh, dass es nun klappt, aber auch etwas enttäuscht. Bisher scheint es mir zwar nicht so, dass die in Mathias Schäfers Artikel angesprochenen Probleme in meinem Projekt auftreten könnten, jedoch war ich schon etwas stolz, meinen Code nach den dort formulierten Richtlinien organisiert zu haben.
                Und es hat auch schon alles funktioniert, die „charaktere“ sind noch umfangreicher als hier vorgestellt, ich konnte verschiedene davon instanzieren und mit „item“-Objekten, die verschiedene Werte hatten, ausstatten.
                In meinen (bescheidenen) Augen war das schon super objektorientiert.

                Und nun scheitern diese Prinzipien an so etwas (wieder in meinen Augen) trivialen wie dem erneuten abspeichern eines Objekts an einer anderen Stelle. Nun gut, ich will nicht unzufrieden sein, da es nun funktioniert.
                Und gelernt habe ich ja auch einiges. ;-)

                Ich bedanke mich bei allen ganz herzlich für die vielen ausführlichen Erklärungen und kompetenten Hilfestellungen. Das ist schon ein tolles Forum mit vielen lieben Leuten.
                Danke sehr und weiterhin viel Freude an der Sache!

                Alles Gute

                huhu

            2. [code lang=javascript]function clone1(o) {
                      function c(o) {
                              for (var i in o) {
                                      this[i] = o[i];
                              }
                      }
                      return new c(o);
              }

              Die Funktion macht nichts anderes als ein leeres Objekt erzeugen und mit for-in Member rüberkopieren (bzw. bei Objekten referenzieren).
              Dafür ist kein Konstruktor und keine Instantiierung nötig, man kann auch einfach ein leeres Objekt mit {} erzeugen.

              function clone2(obj) {
                      if(obj == null || typeof(obj) != 'object') return obj;
                      var c = new obj.constructor();
                      for(var key in obj) {
                              c[key] = clone2(obj[key]);
                      }
                      return c;
              }

              Die Funktion macht alles doppelt, sie erzeugt eine neue Instanz mithilfe des Konstruktors, dann kopiert sie zusätzlich alle Member zu ihm herüber - aber sie ruft sich für jeden Member rekursiv auf. Das macht für ein ganz bestimmten Fall Sinn, nämlich das Kopieren von Object-Strukturen. Aber für Primitives (String, Boolean, Number...) erzeugt es Objects, was absolut Banane ist. Objects werden referenziert, Primitives kopiert. Lass die Finger von solchen Funktionen. Sie sind nicht durchdacht oder gehen von ganz bestimmten Fällen aus.

              function charakter() {
                      var charakter = this;

              Hier legst du eine lokale Variable an als Referenz auf die Instanz

              charakter.attributeHinzufuegen = function
                      charakter.werte = function () {

              Hier notierst du Closures, die die Variable charakter einschließen

              charakter.staerke = staerkeNeu;
                                     charakter.geschick = geschickNeu;
                                     charakter.vitalitaet = vitalitaetNeu;
                              return new Array(charakter.staerke,charakter.geschick,charakter.vitalitaet);

              Hier greifst du auf die eingeschlossene Variable zu. Der Wert der Variable ist der, mit dem du die Variable beim ersten und einzigen Ausführen der Konstruktorfunktion angelegt hast!

              var charakter0 = new charakter();
              var charakter1 = clone1(charakter0);
              charakter0.attributeHinzufuegen(12,2,19);
              charakter1.attributeHinzufuegen(14,8,2);
              // gibt zweimal „14,8,2“ aus:
              alert(charakter0.werte());
              alert(charakter1.werte());

              Das ist ganz klar: Du arbeitest immer noch mit »privaten Variablen«, d.h. mit Closures!

              Du kopierst das Funktionsobjekt werte. Diese ist jedoch eine Closure, die charakter einschließt. Und charakter verweist auf die Instanz, die du hier charakter0 nennst.

              Wenn du mal schreiben würdest:

              charakter.werte = function () {
                 alert(charakter === this); // false
                 alert(charakter === window.charakter0); // true
              }

              würde das zeigen, dass charakter gar nicht auf die Kopie, sondern die Vorlage verweist.

              Wenn du hier auf das Objekt verweisen willst, an dem die Methode hängt und in dessen Kontext sie ausgeführt wird, dann musst du direkt this verwenden. Denn charakter ist eine eingeschlossene Variable, die als Referenz auf die *andere* Instanz angelegt wurde.

              Alles in allem würde ich dir Vorschlagen, zwei Programmiertechniken nicht so unbedenklich zu mischen:

              • Neue Objekte durch Konstruktoren und im Konstruktor definieren Methoden (d.h. immer Closures)
              • Neue Objekte durch Kopien

              Beide Techniken sind toll, aber siehst an diesem Beispiel, wie sie sich stören können. Ich würde hier bei einer Technik bleiben.

              Erstmal: Keine Closures, alles über den Prototyp notieren:

              function Charakter () {}
              Charakter.prototype = {
                 stärke : 0,
                 geschick : 0,
                 vitalität : 0,
                 methode : function () {}
              };

              Immer mit this zum Zugriff auf die Instanz arbeiten.

              Jetzt würde ich eine spezifische Klonfunktion schreiben, die new Character macht, alle Member der Instanz durchläuft und einfach herüberkopiert.

              Das ist simple and stupid, aber funktioniert, solange du genau dieses Setup hast (Methoden sind bei allen Charaktern gleich, zu kopierende Eigenschaften sind Primitives, Charakter erbt keine weiteren Member).

              Komplizieren könntest du die Sache machen, indem die Methoden nicht kopierst, denn sie existieren an der neuen Instanz schon. Ich weiß aber nicht, welchen Vorteil das bringt, schließlich ist es auch nach dem Überschreiben ein und dasselbe Funktionsobjekt (wg. Copy by Reference). Die Performance-Ersparnis ist wahrscheinlich durch typeof(member) != "function" wieder verloren.

              Wenn du irgendwann Objekte (dazu zählen auch Arrays) anstatt Primitives kopieren möchtest, wird es schwieriger. Dann gehts nur so, wie ich anfangs gesagt hatte und worauf Christoph auch nochmal hingewiesen hatte: Funktion erstellen, das zu kopierende Objekt als Prototyp setzen und die Funktion instantiieren.

              Mathias

              1. Hallo Mathias,

                Das ist ganz klar: Du arbeitest immer noch mit »privaten Variablen«, d.h. mit Closures!

                Ja, das war mir inzwischen auch aufgegangen. Asche auf mein Haupt.

                Erstmal: Keine Closures, alles über den Prototyp notieren:

                function Charakter () {}
                Charakter.prototype = {
                   stärke : 0,
                   geschick : 0,
                   vitalität : 0,
                   methode : function () {}
                };

                Immer mit this zum Zugriff auf die Instanz arbeiten.

                Diese Notation versuche ich mir mal anzueignen.

                Wenn du irgendwann Objekte (dazu zählen auch Arrays) anstatt Primitives kopieren möchtest, wird es schwieriger. Dann gehts nur so, wie ich anfangs gesagt hatte und worauf Christoph auch nochmal hingewiesen hatte: Funktion erstellen, das zu kopierende Objekt als Prototyp setzen und die Funktion instantiieren.

                Das ist schon aktuell. Nun, ich habe ein gutes Gefühl, das nun hinzukriegen.
                Aus einer anderen Perspektive sieht die Welt ja ganz anders aus.

                Liebe Grüße

                huhu

      2. Ah, das liegt daran, dass „for in“ nur die öffentlichen Member sieht?
        Ist das immer so

        Ja. for-in zeigt alle »enumerable« (iterierbaren) Member.
        Das sind bei eigenen Objekten alle Objekteigenschaften (nicht enumerable sind nur einige interne Member). Die sogenannten privaten Member sind überhaupt keine Objekteigenschaften, weder iterierbare noch nicht iterierbare, und daher auch nicht für for-in sichtbar.

        Hätten die clone-Funktionen Zugriff auf die privaten Member, wenn ich sie dem Objekt anhänge und damit aus dem Kontext des Objekts starte?

        Nein, das alleine reicht nicht. Ob sie dem Objekt anhängen oder nicht, ist nicht das entscheidende.

        Die ganze Magie von privaten Membern in JS besteht darin, dass man Funktionen im Konstruktor verschachtelt.

        function Konstruktor () {
           var privateEigenschaft;
           this.verschachtelteFunktion = function () { /* Dies ist eine Closure, die privateEigenschaft einschließt */ };
        }

        Alle Funktionen, die du in der Konstruktorfunktion notierst, schließen dessen lokale Variablen ein. Sie sind somit die einzigen, die nach Ablauf der Konstruktorfunktion noch Zugriff darauf haben.

        Für mich ist es kein Unterschied, ob die Felder privat oder öffentlich sind. Ich hab das nur so gemacht, weil in den Tutorien empfohlen wird, interne Objekte privat zu halten und zur Kommunikation nach außen eine öffentliche Schnittstelle anzubieten.

        Das ist im Prinzip richtig, aber in JavaScript ist das alles sehr speziell und die OOP-Schulmedizin ist in dem Punkt nicht auf JS anwendbar.

        Wenn du das Objekt von außen Klonen willst, dann bau dir eine spezifisch Klonfunktion, die die relevanten Eigenschaften über öffentliche Getter abfragt, eine neue Instanz erstellt und die zuvor ausgelesenen Eigenschaften über die Setter auf die neue Instanz überträgt. Mein Vorschlag wäre, diese gleich als Methode am Objekt anzubieten.

        Mit generischen Klonfunktionen kommst du da jedenfalls nicht weiter, wenn nicht alle Eigenschaften öffentlich sind.

        Mathias

        1. Wow, danke für die ausführlichen Ausführungen. Hat mir sehr geholfen, Javascript-Objekte etwas tiefer zu verstehen.

          Ich werde alle Member public machen. Eine interne Funktion, die alle Variablen einzeln abfragt, ist mir zu umfangreich und müsste ja auch immer mitgewartet werden.

          Alles Gute

          huhu

          1. Moin.

            Ich werde alle Member public machen. Eine interne Funktion, die alle Variablen einzeln abfragt, ist mir zu umfangreich und müsste ja auch immer mitgewartet werden.

            Finde ich verünftig. JavaScript ist nicht Java, man sollte sich davor hüten, Methoden einer Sprache unreflektiert auf eine andere zu übertragen.

            Die in JavaScript vorgesehene Variante der Objektorientierung kennt weder private Member - alle Eigenschaften sind öffentlich - noch Vererbungshierarchien: Möchte man eine JS-'Klasse' erweitern, fügt man einfach die entsprechenden Eigenschaften dem Prototyp hinzu, d.h. kopiert Referenzen auf gemeinsame EIgenschaften ('aggregation').

            Die Sprache ist allerdings mächtig genug, um andere Paradigmen zu unterstützen (z.B. private Eigenschaften durch closures, echte prototypische oder klassenbasierte Vererbung können in wenigen Zeilen Code nachgereicht werden).

            Man sollte sich jedoch über die Konsequenzen des gewählten Programmierstils im Klaren sein: private Eigenschaften über closures bereitzustellen beispielsweise ist nicht wirklich effizient: Im Gegensatz zu Funktionen, die dem Prototyp hinzugefügt werden, muss für Funktionen mit Zugriff auf private Eigenschaften für jede Instanz ein neues Funktionsobjekt mit Referenz auf die lexikalische Umgebung (die lokalen Variablen) der Konstruktorfunktion erzeugt werden.

            Christoph

  2. Was du hier machst, hat im Grunde mit klassischem OOP nichts zu tun. JavaScript ist nicht objektorientiert im klassischen Sinne und du kannst auch keine Instanzen samt privaten Membern klonen. Es gibt nämliche keine wirklichen privaten Eigenschaften in JavaScript, sondern nur eine Möglichkeit, dieses Verhalten zu emulieren. Aus Sicht von JavaScript erstellst du nichts anderes als zwei Closures, die beide die drei Variablen einschließen und somit teilen.

    Das ist alles. Das Objekt, was der Konstruktor liefert, hat demnach nur zwei (wie du es nennen würdest: »öffentliche«) Member, nämlich die beiden Methoden. An die sogenannten »privaten« Member sind bloß lokale Variablen des Konstruktors, daran kommt man »von außen« natürlich nicht dran - ausgenommen die beiden Closures.

      for (var i in o) {  
    

    for-in-Schleifen bringen dich nicht zum Ziel, dein Objekt hat schließlich keine Member außer die Methoden, die du nicht kopieren brauchst.

    Jedoch scheinen beide nicht zu funktionieren, sie liefern zwar eine Referenz, aber kein unabhängiges Objekt.

    Das echte Klonen von Objekten ginge anders, nämlich mit einer neuen Funktion, Zuweisung des alten Objektes als ihr Prototyp und schließliches Instantiieren des Konstruktors.
    Das würde dir bei deinem Problem aber nicht weiterhelfen.

    Ansonsten hoffe ich auf Anregungen zum Klonen.

    • Lege »öffentliche« Member des Instanzobjektes an oder
    • Lege eine priviligiere Klon-Methode an, die imstande ist, auch die eingeschlossenen lokalen Variablen der Konstruktorfunktion zu kopieren.

    this.clone = function () {
       var clone = new this.constructor;
       clone.attributeHinzufuegen(staerke, geschick, vitalitaet);
       return clone;
    }

    Mathias

  3. gruss huhu,

    hier zwei links, die Mathias' ausfuehrungen untermauern sollen:

    »[Object].equals, [Object].dump, [Object].clone« vom 14. 11. 2006
    »[Object].equals, [Object].dump, [Object].clone« vom 17. 03. 2008

    so long - peterS. - pseliger@gmx.net

    --
    »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
    Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
    ie:( fl:) br:> va:( ls:& fo:) rl:) n3;} n4:} ss:} de:µ js:} mo:? zu:]
    1. gruss huhu,

      hier zwei links, die Mathias' ausfuehrungen untermauern sollen:

      »[Object.equals, [Object].dump, [Object].clone«] vom 14. 11. 2006
      »[Object.equals, [Object].dump, [Object].clone«] vom 17. 03. 2008

      so long - peterS. - pseliger@gmx.net

      Danke für die Links, verzeih, dass ich den verlinkten Quellcode nur überflogen habe. Hat mir aber die Komplexität der Problematik schon näher gebracht.

      Alles Gute

      huhu