Start · Sprachen · JavaScript · Referenz · Array.prototype.copyWithin()

Array.prototype.copyWithin()

Methode

Kopiert flach einen Abschnitt des Arrays an eine andere Stelle im selben Array und gibt das veränderte Array zurück, ohne seine Länge zu ändern.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Array.prototype.copyWithin(target, start, end)

Beschreibung

copyWithin() liest die Elemente von start bis ausschließlich end und schreibt sie ab Index target in dasselbe Array. Vorhandene Werte werden dabei überschrieben. Die Länge des Arrays bleibt immer gleich: Was über das Ende hinausragen würde, wird abgeschnitten. Die Methode verändert das Array direkt und gibt eine Referenz auf genau dieses Array zurück, keine Kopie.

Alle drei Indizes dürfen negativ sein und zählen dann vom Ende aus (-1 ist das letzte Element). Überlappen sich Quelle und Ziel, verhält sich die Methode so, als würde der Quellabschnitt vorher zwischengespeichert. Das Ergebnis ist also immer korrekt, egal ob nach links oder rechts verschoben wird.

Im Alltag mit normalen Arrays braucht man copyWithin() selten. Wirklich nützlich ist die Methode bei TypedArrays (TypedArray.prototype.copyWithin() funktioniert genauso), zum Beispiel für Ringpuffer, beim Verschieben von Audio- oder Bilddaten oder beim Entfernen von Einträgen aus Puffern mit fester Größe. Dort arbeitet sie intern ähnlich wie memmove und ist deutlich schneller als eine Schleife in JavaScript.

Die Methode ist generisch: Sie verlangt nur ein Objekt mit einer length-Eigenschaft und Schlüsseln mit ganzzahligem Index. Deshalb lässt sie sich per call() auch auf array-ähnliche Objekte anwenden.

Parameter

Name Typ Default Beschreibung
$target Pflicht number Index, ab dem geschrieben wird (wird zu einer Ganzzahl umgewandelt). Negative Werte zählen vom Ende. Ist target >= length, wird nichts kopiert.
$start number 0 Index, ab dem gelesen wird (einschließlich). Negative Werte zählen vom Ende. Ist start >= length, wird nichts kopiert.
$end number array.length Index, bis zu dem gelesen wird (ausschließlich). Negative Werte zählen vom Ende. Liegt end nach der Umrechnung vor oder auf start, wird nichts kopiert.

Rückgabewert

Typ
Array
Beschreibung
Dasselbe, jetzt veränderte Array (gleiche Referenz, arr.copyWithin(...) === arr).

Beispiele

Grundlagen: Ziel, Start und Ende

console.log([1, 2, 3, 4, 5].copyWithin(0, 3));
// Elemente ab Index 3 nach Index 0

console.log([1, 2, 3, 4, 5].copyWithin(0, 3, 4));
// nur Index 3 nach Index 0

console.log([1, 2, 3, 4, 5].copyWithin(-2, -3, -1));
// negative Indizes zählen vom Ende
[4, 5, 3, 4, 5] [4, 2, 3, 4, 5] [1, 2, 3, 3, 4]

Überlappende Bereiche und In-place-Änderung

const zahlen = [1, 2, 3, 4, 5];
const ergebnis = zahlen.copyWithin(1, 0);

// Überlappung wird korrekt behandelt, die Länge bleibt 5
console.log(ergebnis);
console.log(ergebnis === zahlen); // gleiche Referenz
[1, 1, 2, 3, 4] true

Praxis: Puffer fester Größe nach links schieben (TypedArray)

// Messwerte der letzten 5 Sekunden, der neueste Wert steht am Ende
const messwerte = new Uint8Array([10, 20, 30, 40, 50]);

const neuerWert = (puffer, wert) => {
  puffer.copyWithin(0, 1); // alles um eine Position nach links
  puffer[puffer.length - 1] = wert;
  return puffer;
};

console.log(neuerWert(messwerte, 60));
Uint8Array(5) [20, 30, 40, 50, 60]

Generisch auf einem array-ähnlichen Objekt

const arrayLike = { length: 5, 3: 1 };
const res = Array.prototype.copyWithin.call(arrayLike, 0, 3);
console.log(res);

// Lücken werden als Lücken übernommen (das Ziel wird gelöscht)
console.log([1, , 3].copyWithin(2, 1, 2));
{ '0': 1, '3': 1, length: 5 } [1, <2 empty items>]

// Wichtig · Fallstricke

  • Verändert das Array direkt: Wenn das Original erhalten bleiben soll, vorher kopieren, z. B. mit [...arr].copyWithin(0, 3). Ein unveränderndes Gegenstück wie bei toSorted() gibt es nicht.
  • Die Länge ändert sich nie: copyWithin() fügt nichts ein und entfernt nichts. Zum Einfügen oder Löschen ist splice() bzw. toSpliced() gedacht.
  • Flache Kopie: Objekte werden per Referenz kopiert. Danach zeigen zwei Positionen auf dasselbe Objekt.
  • end ist ausschließlich, genau wie bei slice(). Das ist ein häufiger Grund für Fehler um genau ein Element.
  • Dünn besetzte Arrays: Leere Stellen in der Quelle werden nicht mit undefined gefüllt. Stattdessen wird die Zielposition gelöscht, sie bleibt also ebenfalls leer.
  • Bei eingefrorenen Arrays (Object.freeze) wird ein TypeError ausgelöst, sobald tatsächlich geschrieben werden müsste.
  • Kompatibilität: in allen modernen Browsern und in Node.js ab Version 4 verfügbar, nicht im Internet Explorer. Die Variante für TypedArrays wird ebenso breit unterstützt.