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

TypedArray.prototype.with()

Methode

Gibt eine Kopie des typisierten Arrays zurück, in der der Wert an <code>index</code> durch <code>value</code> ersetzt ist. Das Original bleibt unverändert.

seit JavaScript ES2023 (Baseline 2023: Chrome 110, Firefox 115, Sa Kategorie: method-property

Signatur

TypedArray.prototype.with(index, value)

Beschreibung

with() ist die kopierende Entsprechung zur Zuweisung per Klammernotation (ta[i] = x). Statt das bestehende typisierte Array zu verändern, erzeugt die Methode ein neues Array vom gleichen Typ (z. B. Uint8Array bleibt Uint8Array) mit gleicher Länge. Nur das Element an der angegebenen Position ist anders.

Die Methode eignet sich für unveränderliche Datenflüsse, etwa bei Zustandsverwaltung (React, Redux), bei Undo-Verläufen oder wenn ein Puffer von mehreren Codestellen gemeinsam genutzt wird und nicht versehentlich verändert werden darf. Zusammen mit toSorted() und toReversed() gehört sie zu den „Change Array by Copy“-Methoden aus ES2023.

Negative Indizes zählen vom Ende: -1 ist das letzte Element. Anders als bei der Klammernotation, die ungültige Indizes stillschweigend ignoriert, wirft with() bei einem Index außerhalb des gültigen Bereichs einen RangeError. Der Wert wird wie bei jeder Zuweisung an ein typisiertes Array in den Elementtyp umgewandelt, kann also abgeschnitten, gerundet oder begrenzt werden.

Parameter

Name Typ Default Beschreibung
$index Pflicht number Position des zu ersetzenden Elements, beginnend bei 0. Wird in eine Ganzzahl umgewandelt. Negative Werte zählen vom Ende (index + length).
$value Pflicht number | bigint Neuer Wert für die Position. Wird in den Elementtyp umgewandelt: bei BigInt64Array/BigUint64Array per ToBigInt, sonst per ToNumber.

Rückgabewert

Typ
TypedArray
Beschreibung
Ein neues typisiertes Array vom gleichen Typ und mit gleicher Länge wie das Original. Das Element an index ist durch value ersetzt. Das neue Array hat einen eigenen ArrayBuffer.

Beispiele

Einen Wert ersetzen, ohne das Original zu verändern

const original = new Uint8Array([10, 20, 30, 40]);
const geaendert = original.with(1, 99);

console.log(geaendert); // neue Kopie
console.log(original);  // unverändert
console.log(geaendert.constructor.name);
Uint8Array(4) [10, 99, 30, 40] Uint8Array(4) [10, 20, 30, 40] Uint8Array

Negativer Index: letztes Element ersetzen

const messwerte = new Float32Array([1.5, 2.5, 3.5]);
const korrigiert = messwerte.with(-1, 4.25);

console.log(korrigiert);
Float32Array(3) [1.5, 2.5, 4.25]

Typumwandlung: Überlauf und Begrenzung

const bytes = new Uint8Array([0, 0]);
console.log(bytes.with(0, 300));      // 300 mod 256 = 44
console.log(bytes.with(0, -1));       // läuft zu 255 über

const clamped = new Uint8ClampedArray([0, 0]);
console.log(clamped.with(0, 300));    // auf 255 begrenzt

const big = new BigInt64Array([1n, 2n]);
console.log(big.with(1, 42n));
Uint8Array(2) [44, 0] Uint8Array(2) [255, 0] Uint8ClampedArray(2) [255, 0] BigInt64Array(2) [1n, 42n]

Unveränderlicher Pixel-Zustand mit Fehlerbehandlung

// RGBA-Pixel als unveränderlicher Zustand
let pixel = new Uint8ClampedArray([255, 128, 0, 255]);

const setzeKanal = (px, kanal, wert) => {
  try {
    return px.with(kanal, wert);
  } catch (err) {
    console.error(`${err.name}: Kanal ${kanal} existiert nicht`);
    return px;
  }
};

const verlauf = [pixel];
pixel = setzeKanal(pixel, 3, 128); // Alpha halbieren
verlauf.push(pixel);
pixel = setzeKanal(pixel, 7, 0);   // ungültiger Index

console.log(verlauf[0], verlauf[1]);
RangeError: Kanal 7 existiert nicht Uint8ClampedArray(4) [255, 128, 0, 255] Uint8ClampedArray(4) [255, 128, 0, 128]

// Wichtig · Fallstricke

  • RangeError statt stillem Ignorieren: ta[10] = 1 auf einem Array der Länge 4 bewirkt nichts, ta.with(10, 1) wirft einen RangeError. Das gilt auch für index < -length.
  • Typumwandlung: Werte werden wie bei jeder Zuweisung umgewandelt. Bei Integer-Arrays gibt es einen Überlauf (Modulo), bei Uint8ClampedArray wird begrenzt, NaN wird zu 0. Bei BigInt-Arrays führt ein number als value zu einem TypeError, bei anderen Arrays ein bigint.
  • Reihenfolge der Auswertung: value wird vor der Indexprüfung umgewandelt. Seiteneffekte von valueOf() finden also auch dann statt, wenn danach ein RangeError folgt.
  • Kein Species: Das Ergebnis ist immer ein Array des eingebauten Typs. Symbol.species und Unterklassen-Konstruktoren werden nicht verwendet.
  • Performance: Jeder Aufruf kopiert das komplette Array (O(n)). Für viele Änderungen hintereinander in großen Puffern ist es günstiger, einmal mit slice() zu kopieren und dann direkt zuzuweisen.
  • Kompatibilität: Verfügbar ab Chrome/Edge 110, Firefox 115, Safari 16 und Node.js 20. Für ältere Umgebungen gibt es Polyfills, z. B. core-js.