Signatur
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
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);
Negativer Index: letztes Element ersetzen
const verlauf = [10, 20, 30, 40];
const korrigiert = verlauf.with(-1, 45);
console.log(korrigiert);
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);
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());
// Wichtig · Fallstricke
- Kein Verlängern möglich: Anders als
arr[10] = xwirftwith()einenRangeError, wennindex >= lengthoderindex < -lengthist. - 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 MethodeTypedArray.prototype.with()gibt es ebenfalls.