Felix Riesterer: Array in ein anderes Array kopieren ohne ein neues zu erzeugen

Beitrag lesen

Lieber LanX!,

a=[];

b=[1,2,3];
a=b;

  
hier wird zuerst eine (globale) Variable "a" initialisiert und eine Referenz auf eine Objektinstanz des Prototypen "Array" als Wert zugewiesen. Bei "b" verhält es sich genauso, nur mit dem Unterschied, dass das Objekt, auf welches "b" verweist, noch drei Eigenschaften erhält, nämlich die drei Felder mit den Zahlenwerten 1-3.  
  
Anschließend wird der Wert der Variablen "a" komplett überschrieben, indem eine (zweite) Referenz auf das Objekt, welches in der Variablen "b" bereits referenziert wird, in "a" abgelegt wird. Somit ist die Variablen "a" zu einem Alias für die Variablen "b" geworden. Das ursprünglich in "a" referenzierte Objekt wandert in den Mülleimer und wird vom garbage collector aufgefressen.  
  
War das so richtig?  
  

> ~~~javascript

a=[];  

> b=[1,2,3];  
> a=b.slice(0);

In den ersten beiden Zeilen gilt das bereits oben beschriebene Vorgehen. Anschließend wird eine Methode des Array-Objektes angewandt, um das Array-Objekt in "a" zu verändern. Die Methode "slice" extrahiert die Elemente des Arrays "b", beginnend mit dem bei Index "0" (also das erste) und endend mit dem letzten. Da Du keinen zweiten Parameter bei slice angegeben hast, wird der wie ein false oder "-1" gewertet, was soviel bedeutet, wie "bis einschließlich dem letzten Element".

Dadurch steht in "a" keine Referenz auf ein und dasselbe Objekt wie in "b", sondern eine Referenz auf die anfangs initialisierte Instanz des Prototypen "Array". In diesem Beispiel gibt es also zwei unterschiedliche Array-Objekte.

Anzumerken ist noch, dass die Werte, die in "a" über splice eingefügt wurden innerhalb von JavaScript keine Referenzen auf die jeweiligen "Original-Werte" in "b" sind, da Integer-Zahlen im Regelfall nicht als neue "vollständige" Objekte behandelt werden, sondern als primitive Datentypen. Hier wurden also tatsächlich Kopien der Werte angefertigt. In anderen Worten: In "a" stehen echte Zahlenwerte, keine Referenzen auf die entsprechenden Felder in "b".

Oder habe ich das falsch interpretiert?

a=[];

b=[1,2,3];
for (i in b) {a[i]=b[i]};

  
Auch hier gilt in den ersten beiden Zeilen das oben beschriebene Vorgehen. Anschließend wird durch eine For-Schleife im Array "a" ein Wert eingetragen, der dem in Array "b" entspricht. Allerdings bin ich mir nicht sicher, ob auch hier nur Kopien der Integer-Werte erstellt werden, oder ob a[i] kein primitiver Datentyp ist, sodass a[i] eine Referenz auf b[i] darstellt. Ich vermute aber ganz stark ersteres, also auch wieder echte Zahlenwerte, keine Referenzen auf die entsprechenden Felder in "b".  
  

> Und weißt du auch was `==`{:.language-javascript} bei Objekten abprüft???  
  
Ist Deine Fragezeichen-Taste kaputt?  
  
Der `==`{:.language-javascript} Operator prüft nur, ob der Wert als gleich \_interpretiert\_ werden kann. Eine eventuelle Typenumwandlung wird intern automatisch vorgenommen. Deshalb muss man in Fällen wie `0 == false`{:.language-javascript} wissen, dass eine Integer-Zahl mit dem Wert null auch als ein Boolsches "falsch" verstanden werden kann. Will man hier darauf prüfen, ob auch der Datentyp identisch ist, braucht es den `===`{:.language-javascript} Operator.  
  
Als "Perler" magst Du vielleicht noch prüfen können, ob Du es mit dem Objekt selbst, oder nur einer Referenz auf es selbst zu tun hast, in JavaScript ist das so nicht möglich. Dazu ist JS zu dynamisch - und das ist auch gut so.  
  
Liebe Grüße,  
  
Felix Riesterer.

-- 
ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)