Start · Sprachen · JavaScript · Referenz · SharedArrayBuffer.prototype.slice()

SharedArrayBuffer.prototype.slice()

Methode

Gibt einen neuen <code>SharedArrayBuffer</code> mit einer Kopie der Bytes von <code>start</code> (inklusive) bis <code>end</code> (exklusiv) zurück.

seit JavaScript ES2017 Kategorie: method-property

Signatur

SharedArrayBuffer.prototype.slice(start, end)

Beschreibung

Mit slice() wird ein Byte-Bereich eines SharedArrayBuffer in einen neuen, eigenständigen SharedArrayBuffer kopiert. Die Methode arbeitet genauso wie ArrayBuffer.prototype.slice(), liefert aber wieder einen gemeinsam nutzbaren Speicherbereich, den man per postMessage() an Worker weitergeben kann.

Wichtig: Das Ergebnis ist eine Kopie und keine Sicht auf denselben Speicher. Was später in den Originalpuffer geschrieben wird, taucht in der Kopie nicht auf, und umgekehrt genauso wenig. Brauchst du nur eine Sicht auf einen Teilbereich, ohne etwas zu kopieren, nimm stattdessen eine typisierte Array-Ansicht mit Offset, zum Beispiel new Int32Array(sab, byteOffset, length).

Negative Indizes zählen vom Ende des Puffers aus. Werte außerhalb des Bereichs werden auf 0 bis byteLength begrenzt. Ist end kleiner oder gleich start, entsteht ein leerer Puffer mit der Länge 0.

Ein typischer Anwendungsfall ist ein Schnappschuss eines gemeinsam genutzten Puffers, etwa um den aktuellen Stand eines Ringpuffers oder Zustandsspeichers unabhängig von weiteren Schreibvorgängen der Worker zu sichern.

Parameter

Name Typ Default Beschreibung
$start number 0 Byte-Index (nullbasiert), ab dem kopiert wird (inklusive). Negative Werte zählen vom Ende aus (byteLength + start). Nicht-numerische Werte werden in Ganzzahlen umgewandelt.
$end number byteLength Byte-Index, vor dem das Kopieren endet (exklusiv). Negative Werte zählen vom Ende aus. Werte größer als byteLength werden auf byteLength begrenzt.

Rückgabewert

Typ
SharedArrayBuffer
Beschreibung
Ein neuer SharedArrayBuffer mit den kopierten Bytes. Seine byteLength ist max(end - start, 0) (nach der Normalisierung der Indizes). Ist der Originalpuffer wachstumsfähig, ist die Kopie trotzdem nicht wachstumsfähig.

Beispiele

Grundlegende Verwendung und negative Indizes

const sab = new SharedArrayBuffer(16);
const view = new Uint8Array(sab);
view.forEach((_, i) => { view[i] = i; });

const teil = sab.slice(4, 8);
console.log(teil.byteLength, [...new Uint8Array(teil)]);

// Letzte 3 Bytes
const ende = sab.slice(-3);
console.log([...new Uint8Array(ende)]);

// Leerer Bereich
console.log(sab.slice(10, 5).byteLength);
4 [ 4, 5, 6, 7 ] [ 13, 14, 15 ] 0

Kopie statt Sicht – Änderungen sind unabhängig

const sab = new SharedArrayBuffer(8);
const original = new Int32Array(sab);
original[0] = 42;

const kopie = new Int32Array(sab.slice(0, 4));
original[0] = 99; // Original ändern

console.log(kopie[0]);    // bleibt 42
console.log(original[0]); // 99
console.log(kopie.buffer instanceof SharedArrayBuffer);
42 99 true

Konsistenter Schnappschuss eines Worker-Puffers (Node.js)

import { Worker } from 'node:worker_threads';

const sab = new SharedArrayBuffer(4 * Int32Array.BYTES_PER_ELEMENT);
const zaehler = new Int32Array(sab);

const worker = new Worker(`
  const { workerData } = require('node:worker_threads');
  const z = new Int32Array(workerData);
  for (let i = 0; i < 1000; i++) Atomics.add(z, 0, 1);
`, { eval: true, workerData: sab });

worker.on('exit', () => {
  // Stand einfrieren, bevor weitere Schreibzugriffe passieren
  const snapshot = new Int32Array(sab.slice(0));
  console.log('Zählerstand:', snapshot[0]);
});
Zählerstand: 1000

// Wichtig · Fallstricke

  • Keine atomare Kopie: slice() kopiert Byte für Byte ohne Synchronisation. Schreiben andere Worker gleichzeitig in den Puffer, kann der Schnappschuss uneinheitlich sein und zerrissene Werte enthalten. Sichere solche Zugriffe mit Atomics.wait()/Atomics.notify() oder einer eigenen Sperre ab.
  • Speicherverbrauch: Bei jedem Aufruf wird neuer Speicher belegt. Wenn du nur lesen willst, ist eine typisierte Array-Ansicht mit Offset (new Uint8Array(sab, offset, len)) günstiger.
  • Wachstumsfähige Puffer: Auch wenn das Original mit maxByteLength angelegt wurde, ist das Ergebnis immer ein Puffer mit fester Länge.
  • Browser-Kompatibilität: SharedArrayBuffer gibt es nur in cross-origin isolated Kontexten. Die Seite muss dafür mit den Headern Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp ausgeliefert werden (prüfen mit crossOriginIsolated). Diese Einschränkung ist eine Schutzmaßnahme gegen Spectre. In Node.js steht die Klasse ohne Einschränkung zur Verfügung.
  • Wird die Methode auf einem normalen ArrayBuffer aufgerufen, zum Beispiel über call(), wirft sie einen TypeError.