Start · Sprachen · JavaScript · Referenz · TypedArray.prototype.subarray()

TypedArray.prototype.subarray()

Methode

Gibt eine neue <code>TypedArray</code>-Ansicht auf denselben <code>ArrayBuffer</code> zurück. Sie umfasst die Elemente von <code>begin</code> bis ausschließlich <code>end</code>, ohne Daten zu kopieren.

seit JavaScript ES2015 Kategorie: method-property

Signatur

TypedArray.prototype.subarray(begin, end)

Beschreibung

subarray() erzeugt ein neues typisiertes Array vom selben Typ (z. B. Uint8Array oder Float32Array). Es greift auf denselben Speicher zu wie das Original. Es werden keine Daten kopiert, sondern nur eine neue Ansicht mit angepasstem byteOffset und angepasster length angelegt. Schreibt man in das Teilarray, ändert sich deshalb auch das Original, und umgekehrt.

Damit eignet sich die Methode gut, um große Binärpuffer ohne Kopieraufwand in Abschnitte zu teilen. Typische Fälle sind Header und Nutzdaten eines Netzwerkpakets, einzelne Bildzeilen in Pixeldaten oder Blöcke beim Streaming. Das spart Speicher und ist deutlich schneller als eine Kopie.

Die Indizes werden wie bei Array.prototype.slice() ausgewertet. Negative Werte zählen vom Ende aus, Werte außerhalb des Bereichs werden auf 0 bzw. length begrenzt. end selbst gehört nicht mehr zum Ergebnis. Liegt begin hinter end, ist das Ergebnis ein leeres Array. Einen Fehler gibt es dabei nicht.

Wer eine unabhängige Kopie braucht, verwendet stattdessen TypedArray.prototype.slice().

Parameter

Name Typ Default Beschreibung
$begin number 0 Index des ersten Elements, das enthalten sein soll. Negative Werte zählen vom Ende aus (-2 steht für length - 2).
$end number length Index, vor dem die Ansicht endet (exklusiv). Negative Werte zählen vom Ende aus. Ohne Angabe reicht die Ansicht bis zum Ende.

Beispiele

Teilansicht teilt den Speicher mit dem Original

const daten = new Uint8Array([10, 20, 30, 40, 50]);
const mitte = daten.subarray(1, 4);

console.log(mitte);          // Elemente 1 bis 3
mitte[0] = 99;               // schreibt in denselben Puffer
console.log(daten);
console.log(mitte.buffer === daten.buffer);
Uint8Array(3) [20, 30, 40] Uint8Array(5) [10, 99, 30, 40, 50] true

Negative Indizes und byteOffset

const werte = new Float32Array([1.5, 2.5, 3.5, 4.5]);
const letzteZwei = werte.subarray(-2);

console.log(letzteZwei);
console.log(letzteZwei.byteOffset); // 2 Elemente × 4 Byte
console.log(werte.subarray(3, 1).length); // begin > end → leer
Float32Array(2) [3.5, 4.5] 8 0

Netzwerkpaket in Header und Nutzdaten zerlegen

// Paket: 4 Byte Header, danach die Nutzdaten
const paket = new Uint8Array([0x01, 0x00, 0x00, 0x05, 72, 97, 108, 108, 111]);

const header = paket.subarray(0, 4);
const nutzdaten = paket.subarray(4);

const laenge = new DataView(header.buffer, header.byteOffset, 4).getUint16(2);
const text = new TextDecoder().decode(nutzdaten);

console.log(`Version ${header[0]}, Länge ${laenge}: ${text}`);
Version 1, Länge 5: Hello

Großen Puffer in Blöcken verarbeiten, ohne zu kopieren

const puffer = new Uint8Array(10).map((_, i) => i);
const blockGroesse = 4;

for (let i = 0; i < puffer.length; i += blockGroesse) {
  const block = puffer.subarray(i, i + blockGroesse);
  const summe = block.reduce((a, b) => a + b, 0);
  console.log(`Block ab ${i}: [${block}] Summe ${summe}`);
}
Block ab 0: [0,1,2,3] Summe 6 Block ab 4: [4,5,6,7] Summe 22 Block ab 8: [8,9] Summe 17

// Wichtig · Fallstricke

  • Keine Kopie: Änderungen am Teilarray wirken sich auf das Original aus, und umgekehrt. Für eine unabhängige Kopie nimmt man slice(). Bei Array.prototype.slice() wird immer kopiert, was leicht zur Verwechslung führt.
  • Der gesamte Puffer bleibt im Speicher: Solange ein kleines Teilarray existiert, kann der Garbage Collector den großen ArrayBuffer dahinter nicht freigeben. Wer nur wenige Bytes aus einem großen Puffer länger aufbewahren will, sollte sie mit slice() kopieren.
  • Zugriff über .buffer: teil.buffer liefert den ganzen Puffer, nicht nur den Ausschnitt. Bei DataView, postMessage-Transfer oder APIs, die einen ArrayBuffer erwarten, muss man byteOffset und byteLength mitgeben.
  • Übertragene oder abgekoppelte Puffer: Nach einem Transfer (z. B. per postMessage oder ArrayBuffer.prototype.transfer()) ist der Puffer abgekoppelt. Dann haben auch alle Teilarrays die Länge 0.
  • Größenveränderbare Puffer (ES2024): Ohne end auf einem längenverfolgenden Array erzeugt, wächst bzw. schrumpft das Teilarray mit einem resizable ArrayBuffer mit.
  • Unterklassen: Das Ergebnis wird über Symbol.species erzeugt, bei eigenen Unterklassen also mit deren Konstruktor.
  • Die Methode wird in allen modernen Browsern und in Node.js unterstützt. In Node.js ist Buffer.prototype.subarray() eine eigene Variante, die sich genauso verhält.