Start · Sprachen · JavaScript · Referenz · TypedArray.prototype.byteOffset

TypedArray.prototype.byteOffset

Eigenschaft

Gibt an, wie viele Bytes nach dem Anfang des zugrunde liegenden <code>ArrayBuffer</code> bzw. <code>SharedArrayBuffer</code> ein typisiertes Array beginnt.

seit JavaScript ES2015 (Baseline: alle Browser, Node.js 0.10+) Kategorie: method-property

Signatur

get TypedArray.prototype.byteOffset

Beschreibung

byteOffset ist eine schreibgeschützte Zugriffseigenschaft (Getter) auf TypedArray.prototype. Sie liefert die Startposition eines typisierten Arrays (z. B. Uint8Array, Int32Array, Float64Array) innerhalb seines Puffers, gemessen in Bytes – nicht in Elementen. Der Wert wird beim Erzeugen festgelegt, entweder über das zweite Argument des Konstruktors (new Int32Array(buffer, byteOffset, length)) oder indirekt über subarray(), und ändert sich danach nicht mehr.

Wichtig ist die Eigenschaft immer dann, wenn sich mehrere Sichten einen Puffer teilen: beim Parsen von Binärformaten (Dateiköpfe, Netzwerkpakete, WebGL-Vertexdaten), beim Weitergeben von Teilbereichen an APIs, die einen ArrayBuffer erwarten, oder bei Node.js-Buffer-Objekten, die häufig aus einem gemeinsamen Speicherpool stammen. Wer in solchen Fällen einfach view.buffer weiterreicht, ohne byteOffset und byteLength zu berücksichtigen, verarbeitet versehentlich den gesamten Puffer.

Zusammen mit byteLength beschreibt byteOffset exakt den Bytebereich [byteOffset, byteOffset + byteLength), den das Array im Puffer belegt. Bei subarray(begin, end) gilt: neu.byteOffset === alt.byteOffset + begin * BYTES_PER_ELEMENT.

Rückgabewert

Typ
number
Beschreibung
Nicht-negative Ganzzahl: der Abstand in Bytes vom Pufferanfang bis zum ersten Element. Ist der Puffer detached (z. B. nach einem Transfer) oder liegt die Sicht bei einem verkleinerten, größenveränderbaren Puffer außerhalb des gültigen Bereichs, wird 0 zurückgegeben.

Beispiele

Mehrere Sichten auf denselben Puffer

const buffer = new ArrayBuffer(16);

const alles = new Uint8Array(buffer);        // ab Byte 0
const ab4 = new Uint8Array(buffer, 4);       // ab Byte 4
const ints = new Int32Array(buffer, 8, 2);   // ab Byte 8, 2 Elemente

console.log(alles.byteOffset, ab4.byteOffset, ints.byteOffset);
console.log(ints.byteLength);
0 4 8 8

byteOffset bei subarray() – Bytes statt Elemente

const messwerte = new Float64Array(10); // 8 Byte pro Element
const ausschnitt = messwerte.subarray(3, 6);

console.log(ausschnitt.byteOffset);  // 3 * 8
console.log(ausschnitt.byteLength);  // 3 * 8

// Verschachtelte Teilansichten addieren ihre Offsets
const teil = ausschnitt.subarray(1);
console.log(teil.byteOffset);        // 24 + 1 * 8
24 24 32

Exakt den belegten Bereich als eigenen ArrayBuffer kopieren

// Typischer Fallstrick: view.buffer enthält u. U. viel mehr Daten
const paket = new Uint8Array([0xCA, 0xFE, 0x01, 0x02, 0x03, 0x04]);
const nutzdaten = paket.subarray(2); // Kopf (2 Bytes) überspringen

const toExactBuffer = (view) =>
  view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);

console.log(nutzdaten.buffer.byteLength);           // gesamter Puffer
console.log(toExactBuffer(nutzdaten).byteLength);   // nur Nutzdaten
console.log([...new Uint8Array(toExactBuffer(nutzdaten))]);
6 4 [1, 2, 3, 4]

Ausrichtung und detached Puffer

const buffer = new ArrayBuffer(16);

try {
  // Offset muss ein Vielfaches von BYTES_PER_ELEMENT (4) sein
  new Int32Array(buffer, 3);
} catch (err) {
  console.log(err.name);
}

const view = new Uint8Array(buffer, 4);
console.log(view.byteOffset);

// Puffer übertragen -> alte Sicht wird detached
structuredClone(buffer, { transfer: [buffer] });
console.log(view.byteOffset, view.length);
RangeError 4 0 0

// Wichtig · Fallstricke

  • Einheit Bytes: byteOffset zählt immer in Bytes, auch bei Float64Array oder BigInt64Array. Für den Elementindex durch BYTES_PER_ELEMENT teilen.
  • Ausrichtung: Beim Konstruktor muss der Offset ein Vielfaches von BYTES_PER_ELEMENT sein, sonst wird ein RangeError geworfen. Für unausgerichtete Zugriffe DataView verwenden.
  • Schreibgeschützt: Es gibt keinen Setter; eine Zuweisung wird im Sloppy Mode stillschweigend ignoriert und wirft im Strict Mode einen TypeError. Um den Offset zu ändern, eine neue Sicht erzeugen.
  • Detached / Resizable: Nach einem Transfer (structuredClone mit transfer, postMessage, ArrayBuffer.prototype.transfer()) liefert der Getter 0. Das Gleiche gilt, wenn ein größenveränderbarer Puffer (ES2024) so verkleinert wird, dass die Sicht außerhalb liegt.
  • Node.js-Buffer: Kleine Buffer-Objekte (z. B. aus Buffer.from()) stammen oft aus einem 8-KiB-Pool und haben einen byteOffset ungleich 0. Beim Weiterreichen von buf.buffer unbedingt byteOffset und byteLength berücksichtigen.
  • Die Eigenschaft wird in allen modernen Browsern und Node.js unterstützt; das Verhalten bei größenveränderbaren Puffern ist neuer (ES2024).