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

Array.prototype.with()

Methode

Gibt eine Kopie des Arrays zurück, in der der Wert am angegebenen Index ersetzt ist. Das ursprüngliche Array bleibt dabei unverändert.

seit JavaScript ES2023 (Baseline seit Juli 2023: Chrome 110, Firef Kategorie: method-property

Signatur

Array.prototype.with(index, value)

Beschreibung

with() ist das nicht verändernde Gegenstück zur Zuweisung per Klammernotation (arr[i] = wert). Statt das bestehende Array zu verändern, entsteht ein neues Array, in dem genau ein Element ausgetauscht ist. Alle anderen Elemente werden flach kopiert.

Die Methode ist besonders nützlich bei unveränderlichen Datenstrukturen, etwa im Zustand von React-, Redux- oder Vue-Anwendungen. Dort muss eine Änderung eine neue Referenz erzeugen, damit sie erkannt wird. Bisher brauchte man dafür [...arr] mit anschließender Zuweisung oder ein map() mit Indexvergleich.

Negative Indizes zählen vom Ende her: -1 ist das letzte Element, genau wie bei at(). Liegt der Index außerhalb des gültigen Bereichs, wirft with() einen RangeError. Das Array kann mit with() also nicht verlängert werden.

with() gehört zu den „kopierenden“ Array-Methoden aus ES2023, zusammen mit toSorted(), toReversed() und toSpliced(). Die Methode ist generisch und funktioniert auch mit Array-ähnlichen Objekten, die eine length-Eigenschaft besitzen.

Parameter

Name Typ Default Beschreibung
$index Pflicht number Index des Elements, das ersetzt werden soll (ab 0). Negative Werte zählen vom Ende her (index + array.length). Nachkommastellen werden abgeschnitten; undefined oder NaN werden zu 0.
$value Pflicht any Neuer Wert für die angegebene Position. Wird der Parameter weggelassen, wird undefined eingesetzt.

Rückgabewert

Typ
Array
Beschreibung
Ein neues Array mit derselben Länge wie das Original, in dem an der Position index der Wert value steht. Das Ergebnis ist immer ein normales Array, auch wenn das Original eine Unterklasse ist.

Beispiele

Einfaches Ersetzen ohne Veränderung des Originals

const farben = ['rot', 'grün', 'blau'];
const neu = farben.with(1, 'gelb');

console.log(neu);
console.log(farben);
[ 'rot', 'gelb', 'blau' ] [ 'rot', 'grün', 'blau' ]

Negativer Index: letztes Element ersetzen

const verlauf = [10, 20, 30, 40];
const korrigiert = verlauf.with(-1, 45);

console.log(korrigiert);
[ 10, 20, 30, 45 ]

Unveränderliches Zustands-Update (z. B. React)

const todos = [
  { id: 1, text: 'Einkaufen', erledigt: false },
  { id: 2, text: 'Sport', erledigt: false }
];

const umschalten = (liste, id) => {
  const i = liste.findIndex((t) => t.id === id);
  if (i === -1) return liste;
  return liste.with(i, { ...liste[i], erledigt: !liste[i].erledigt });
};

const neueTodos = umschalten(todos, 2);
console.log(neueTodos[1].erledigt, todos[1].erledigt);
console.log(neueTodos === todos);
true false false

RangeError bei ungültigem Index und Verkettung

const zahlen = [3, 1, 2];

try {
  zahlen.with(5, 99);
} catch (err) {
  console.log(err.name);
}

// Verkettung mit anderen kopierenden Methoden
console.log(zahlen.with(0, 0).toSorted());
RangeError [ 0, 1, 2 ]

// Wichtig · Fallstricke

  • Kein Verlängern möglich: Anders als arr[10] = x wirft with() einen RangeError, wenn index >= length oder index < -length ist.
  • Nur flache Kopie: Objekte im Array werden nicht geklont, sondern per Referenz übernommen. Wer ein verschachteltes Objekt ändern will, muss es selbst kopieren, z. B. mit { ...obj }.
  • Lücken werden aufgefüllt: Löchrige Arrays (sparse arrays) ergeben ein Array ohne Lücken. Leere Stellen werden zu undefined.
  • Leistung: Jeder Aufruf kopiert das gesamte Array, die Laufzeit wächst also linear mit der Länge (O(n)). In engen Schleifen mit vielen Einzeländerungen ist es besser, einmal mit [...arr] zu kopieren und die Kopie direkt zu verändern.
  • Kompatibilität: Verfügbar ab Chrome/Edge 110, Firefox 115, Safari 16 und Node.js 20. Für ältere Umgebungen gibt es einen Polyfill, z. B. core-js. Eine entsprechende Methode TypedArray.prototype.with() gibt es ebenfalls.