Javascript: Arrays kopieren

Banale Aufgabe: Erstelle eine unabhängige Kopie von einem Javascript-Array. Was erstmal billig klingt entpuppt sich für unwissende, PHP verwöhnte Entwickler doch als tricky.

var colors = ["red", "blue", "green"]; var copied = colors;  copied[0] = "magenta";  console.log(colors); //["magenta", "blue", "green"] console.log(copied); //["magenta", "blue", "green"] 

In diesem Beispiel sehen wir also, dass die vermeintliche Kopie eigentlich das gleiche Element ist. Gleiches gilt entsprechend für das Übergeben eines Arrays als Parmeter an eine Funktion.

var colors = ["red", "blue", "green"];  test(colors); console.log(colors); //["magenta", "blue", "green"]  function test(arr) { 	arr[0] = "magenta"; } 

Offensichtlich nicht wie von PHP gewohnt By Value sondern By Reference.

Ja und wie geht es nun?

Enter Array.slice. Damit lassen sich wirkliche Kopien erstellen.

var colors = ["red", "blue", "green"]; var colorscopy = colors.slice(); //or colors.slice(0, colors.length);  colorscopy[0] = "magenta";  console.log(colors); //["red", "blue", "green"] console.log(colorscopy); //["magenta", "blue", "green"] 

Tada! Als Alternative könnte man sich auch selbst was zusammenbasteln, etwa so:

for (var i in original) { 	copy[i] = original[i]; } 

Wer cool ist und / oder mit der Bezeichnung slice nicht klarkommt, kann es auch elegant per Prototyp lösen:

Array.prototype.copy = function()  { 	return this.slice(); }  var colors = ["red", "blue", "green"]; var colorscopy = colors.copy(); //... 

[Ergänzung: So cool scheint das doch nicht zu sein…

One mis-feature that is often used is to extend Object.prototype or one of the other built in prototypes.

This technique is called monkey patching and breaks encapsulation. While used by widely spread frameworks such as Prototype, there is still no good reason for cluttering built in types with additional non-standard functionality.

Außerdem bekommt man so Probleme mit for-in-Loops, bei denen dann auch die Funktion aus dem Prototyp mit auftaucht (danke an Steffen).

(Quelle)]

Hätten wir das also abgehakt. Aber es gibt noch einen…

Bonus! Arraygröße erweitern und verkürzen

Javascript Arrays verlängern sich ganz bequem, indem sie den Zwischenraum mit undefined ausfüllen:

var colors = ["red", "blue", "green"]; colors[7] = "yellow";  alert(colors.length); //8 console.log(colors); //["red", "blue", "green", undefined, undefined, undefined, undefined, "yellow"] 

Was viele nicht wissen: Array.length ist nicht readonly. Damit lassen sich Arrays auch verkürzen (allerdings nicht verlängern):

var colors = ["red", "blue", "green"]; colors.length = 2; console.log(colors); //["red", "blue"] 

Falls es mal jemand gebrauchen sollte.

[Ergänzung 2:

var copied = [].concat(original); 

Ein weiterer geschmeidiger Weg, um ein Array zu kopieren (danke an Fabian).]


Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0