Signatur
Beschreibung
transfer() überträgt den Inhalt eines ArrayBuffer in einen neuen Puffer und macht den alten Puffer danach unbrauchbar („detached“). Seine byteLength ist dann 0, und jeder Zugriff über daran gebundene TypedArrays oder DataViews schlägt fehl oder liefert nichts mehr. Das entspricht einer Übergabe des Besitzes: Nach dem Aufruf verweist nur noch der neue Puffer auf die Daten.
Da die Engine den zugrunde liegenden Speicher oft einfach umhängt, statt ihn zu kopieren, ist transfer() meist deutlich günstiger als eine manuelle Kopie mit slice(). Mit dem optionalen Parameter newLength lässt sich der Puffer dabei gleich vergrößern (neue Bytes werden mit 0 gefüllt) oder verkleinern (überschüssige Bytes werden verworfen).
Typische Einsatzfälle:
- Eine API bekommt einen Puffer, und der Aufrufer soll ihn danach nicht mehr verändern können (Schutz vor nachträglicher Manipulation).
- Einen Puffer effizient vergrößern oder verkleinern, ohne Daten doppelt im Speicher zu halten.
- Den Zustand „detached“ bewusst herbeiführen, analog zu
structuredClone(buf, { transfer: [buf] })oderpostMessagemit Transfer-Liste.
Der neue Puffer behält die Größenänderbarkeit des Originals: Ist der alte Puffer resizable (mit maxByteLength erzeugt), ist es auch der neue, mit derselben maxByteLength. Soll das Ergebnis fest sein, nimmt man transferToFixedLength().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $newLength | number | this.byteLength | Die byteLength des neuen Puffers. Ist sie größer als die bisherige, werden die zusätzlichen Bytes mit 0 gefüllt, ist sie kleiner, wird abgeschnitten. Bei einem größenänderbaren Puffer darf sie maxByteLength nicht überschreiten. |
Rückgabewert
ArrayBuffer mit dem Inhalt des Originals (ggf. gekürzt oder mit Nullen aufgefüllt). Die Größenänderbarkeit und maxByteLength werden vom Original übernommen. Der ursprüngliche Puffer ist danach abgetrennt (detached === true).Beispiele
Grundlagen: Inhalt übertragen, Original wird abgetrennt
const buf = new ArrayBuffer(8);
const view = new Uint8Array(buf);
view[0] = 42;
const moved = buf.transfer();
console.log(buf.detached, buf.byteLength); // Original ist leer
console.log(moved.detached, moved.byteLength);
console.log(new Uint8Array(moved)[0]);
console.log(view.length); // alte Sicht ist unbrauchbar
Puffer vergrößern und verkleinern
const buf = new ArrayBuffer(4);
new Uint8Array(buf).set([1, 2, 3, 4]);
// Vergrößern: neue Bytes sind 0
const bigger = buf.transfer(6);
console.log([...new Uint8Array(bigger)]);
// Verkleinern: überschüssige Bytes fallen weg
const smaller = bigger.transfer(2);
console.log([...new Uint8Array(smaller)]);
console.log(bigger.detached);
Praxis: Puffer an eine Funktion übergeben und vor Manipulation schützen
const processAsync = async (input) => {
// Besitz übernehmen – der Aufrufer kann die Daten nicht mehr ändern
const owned = input.transfer();
await new Promise((resolve) => setTimeout(resolve, 10));
const bytes = new Uint8Array(owned);
return bytes.reduce((sum, b) => sum + b, 0);
};
const data = new Uint8Array([10, 20, 30]).buffer;
const resultPromise = processAsync(data);
// Nachträglicher Schreibversuch läuft ins Leere
new Uint8Array(data)[0] = 255; // Sicht hat Länge 0, Zuweisung wird ignoriert
console.log(await resultPromise);
Resizable-Eigenschaft bleibt erhalten
const rbuf = new ArrayBuffer(4, { maxByteLength: 16 });
const t1 = rbuf.transfer();
console.log(t1.resizable, t1.maxByteLength);
t1.resize(12);
console.log(t1.byteLength);
try {
t1.transfer(32); // größer als maxByteLength
} catch (e) {
console.log(e.constructor.name);
}
// Wichtig · Fallstricke
- Abgetrennte Puffer: Ruft man
transfer()auf einem bereits abgetrennten Puffer auf, wird einTypeErrorausgelöst. Mitbuf.detachedlässt sich das vorher prüfen. - Alte Sichten: TypedArrays und
DataViews auf dem Original werden nicht automatisch umgehängt. TypedArrays haben danach die Länge0, Zugriffe über eineDataViewlösen einenTypeErroraus. Neue Sichten müssen auf dem zurückgegebenen Puffer erzeugt werden. - RangeError: Wird ausgelöst, wenn
newLengthbei einem größenänderbaren PuffermaxByteLengthüberschreitet oder negativ bzw. zu groß ist. - SharedArrayBuffer: Hat keine
transfer()-Methode, geteilter Speicher lässt sich nicht abtrennen. Auch nicht abtrennbare Puffer, z. B.WebAssembly.Memory.buffer, lösen einenTypeErroraus. - Performance: Ohne Längenänderung (oder bei nicht größenänderbaren Puffern) kann die Engine meist ganz ohne Kopie auskommen. Bei geänderter Länge kann trotzdem kopiert werden, das hängt von der Implementierung ab.
- Kompatibilität: Neu in ES2024. Verfügbar ab Chrome/Edge 114, Firefox 122, Safari 17.4 und Node.js 21. Für ältere Umgebungen gibt es als Ausweichlösung
structuredClone(buf, { transfer: [buf] }), allerdings ohne Längenänderung.