Signatur
Beschreibung
copyWithin() verschiebt bzw. dupliziert einen Bereich von Elementen innerhalb desselben Typ-Arrays (z. B. Uint8Array, Float32Array). Die Elemente von start bis ausschließlich end werden ab Index target hineingeschrieben. Das Array wird direkt verändert (mutiert) und die Länge bleibt immer gleich: Was über das Ende hinausreichen würde, wird abgeschnitten.
Die Methode verhält sich wie Array.prototype.copyWithin(), arbeitet aber auf dem zugrunde liegenden Speicher (ArrayBuffer) und ist dadurch sehr schnell – intern entspricht sie einem memmove. Sie eignet sich ideal für Ringpuffer, das Verschieben von Audio- oder Bilddaten, Scroll-Effekte in Pixelpuffern oder das Entfernen/Einfügen von Blöcken in Binärdaten ohne neue Allokation.
Alle Indizes dürfen negativ sein und werden dann vom Ende aus gezählt (-1 = letztes Element). Überlappende Quell- und Zielbereiche werden korrekt behandelt: Es wird so kopiert, als ob die Quelldaten vorher zwischengespeichert worden wären.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | number | Nullbasierter Zielindex, ab dem die Elemente geschrieben werden. Negative Werte zählen vom Ende. Ist target ≥ Länge, wird nichts kopiert. |
|
| $start | number | 0 | Nullbasierter Index, ab dem kopiert wird. Negative Werte zählen vom Ende. |
| $end | number | this.length | Index, vor dem das Kopieren endet (exklusiv). Negative Werte zählen vom Ende. |
Rückgabewert
Beispiele
Grundlegende Verwendung
const arr = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
// Elemente ab Index 3 an den Anfang kopieren
arr.copyWithin(0, 3);
console.log(arr);
const b = new Uint8Array([1, 2, 3, 4, 5]);
// Index 0–1 nach Index 3 kopieren
b.copyWithin(3, 0, 2);
console.log(b);
Negative Indizes
const data = new Int16Array([10, 20, 30, 40, 50]);
// Die letzten zwei Elemente an den Anfang kopieren
data.copyWithin(0, -2);
console.log(data);
Gleitendes Fenster für Audio-Samples (Puffer nach links schieben)
const WINDOW = 8;
const buffer = new Float32Array(WINDOW);
const pushSamples = (samples) => {
const n = samples.length;
// Alte Daten um n nach links schieben, ohne neuen Speicher anzulegen
buffer.copyWithin(0, n);
// Neue Samples ans Ende schreiben
buffer.set(samples, WINDOW - n);
};
pushSamples(new Float32Array([0.1, 0.2, 0.3]));
pushSamples(new Float32Array([0.4, 0.5]));
console.log(Array.from(buffer, (v) => v.toFixed(1)).join(', '));
Pixelzeilen in einem RGBA-Puffer nach oben scrollen
const width = 4, height = 3, bpp = 4; // RGBA
const rowBytes = width * bpp;
const pixels = new Uint8ClampedArray(width * height * bpp);
// Jede Zeile mit ihrer Zeilennummer füllen
for (let y = 0; y < height; y++) {
pixels.fill(y + 1, y * rowBytes, (y + 1) * rowBytes);
}
// Um eine Zeile nach oben scrollen, letzte Zeile leeren
pixels.copyWithin(0, rowBytes).fill(0, (height - 1) * rowBytes);
console.log(pixels[0], pixels[rowBytes], pixels[2 * rowBytes]);
// Wichtig · Fallstricke
- Mutiert das Original: Anders als
slice()odertoSorted()wird kein neues Array erzeugt. Wer die Ursprungsdaten braucht, muss vorher kopieren (z. B.arr.slice()). - Geteilter Speicher: Alle Ansichten (
subarray(), andere Typ-Arrays,DataView) auf denselbenArrayBuffersehen die Änderung sofort. - Keine Typumwandlung: Es werden rohe Bytes des Elementtyps kopiert – Werte bleiben exakt erhalten, es gibt kein Clamping oder Runden.
- Nicht-ganzzahlige Indizes werden abgeschnitten (
1.7→1),NaN/undefinedgelten als0(bzw. beiendals Länge). - Ist der
ArrayBufferdetached (z. B. nachpostMessagemit Transfer), wird einTypeErrorgeworfen. Bei größenveränderlichen Puffern (resizable) wird die Kopie auf die aktuelle Länge begrenzt. - Die Methode ist nicht generisch: Aufruf auf normalen Arrays oder Objekten via
call()wirft einenTypeError– dafür gibt esArray.prototype.copyWithin(). - Kompatibilität: In allen modernen Browsern und Node.js (ab 4) verfügbar; nicht im Internet Explorer.