Array.prototype.toSpliced()
Two differences from splice, not one: it copies instead of mutating, AND it returns the resulting array instead of the removed elements. The second catches people more than the first.
Demo
Compare the first case with splice: [1,2,3,4,5].splice(1, 2) returns [2, 3] — the removed elements — while toSpliced returns [1, 4, 5], the array you are left with. Same arguments, opposite return value. That is the difference to internalise, and it is why swapping one for the other is not a drop-in change even once mutation stops mattering.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| start | number | yes | Index to begin changing at. Negative counts from the end. |
| skipCount | number | no (to the end) | How many elements to omit from the result. Named skipCount rather than deleteCount, because nothing is deleted — the source is untouched. |
| ...items | any | no (none) | Elements to insert at start in the new array. |
Return value
Array — A NEW array with the changes applied — the RESULT, not the removed elements. That return value is the opposite of splice.
Common patterns
setItems(items.toSpliced(index, 1));
const next = items.toSpliced(2, 0, newItem);
const next = [...items]; next.splice(index, 1);
Examples
Pitfalls
const removed = items.toSpliced(1, 2);
const removed = items.slice(1, 3);
const a = [{n: 1}, {n: 2}]; const b = a.toSpliced(1, 1); b[0].n = 9; a[0].n
const b = structuredClone(a).toSpliced(1, 1);
items.toSpliced(1, 1)
const next = [...items]; next.splice(1, 1);
When to use
- Removing or inserting in state without mutating
- Any place copy-then-splice appears today
- Expression contexts where a three-line copy would not fit
- You want the REMOVED elements → splice, or slice the range first
- You own the array and want it changed in place → splice
- Runtimes older than ES2023 → copy then splice
- Removing by a test rather than an index → filter
Notes
FAQ
Because the two answer different questions. splice mutates, so the array is already updated and the useful thing left to hand back is what it removed. toSpliced does not mutate, so the only useful thing to return is the new array.
items.splice(1, 2); // [2, 3] — removed items.toSpliced(1, 2); // [1, 4] — result