Arrays

JavaScript immutable array methods: toSorted(), toReversed(), toSpliced(), with()

Need to sort or reverse an array without mutating it? Use toSorted(), toReversed(), toSpliced(), and with() to get a new copy instead.

8 minute lesson

~~~

The old sort(), reverse(), and splice() methods mutate the array in place. That surprises you when you expect the original to stay the same.

Say you sort a list of scores to show a leaderboard. You call sort() on the array you also use elsewhere. Now the original order is gone.

const scores = [88, 42, 95, 71]
const sorted = scores.sort((a, b) => b - a)

console.log(scores)  // [95, 88, 71, 42] (mutated!)
console.log(sorted)  // same array reference

ES2023 added four methods that return a new array instead. The original stays untouched. They work in all modern browsers and in Node.js 20+.

toSorted()

Use toSorted() when you need a sorted copy. Pass a comparator, same as with sort().

const scores = [88, 42, 95, 71]
const sorted = scores.toSorted((a, b) => b - a)

console.log(scores)  // [88, 42, 95, 71]
console.log(sorted)  // [95, 88, 71, 42]

If you skip the comparator, it sorts as strings. For numbers, always pass a function. See the sort comparator for details.

toReversed()

toReversed() returns a reversed copy. The original array does not change.

const months = ['Jan', 'Feb', 'Mar']
const reversed = months.toReversed()

console.log(months)   // ['Jan', 'Feb', 'Mar']
console.log(reversed) // ['Mar', 'Feb', 'Jan']

toSpliced()

splice() mutates and returns removed items. toSpliced() returns a new array with the edit applied.

const tasks = ['write', 'review', 'ship']
const updated = tasks.toSpliced(1, 1, 'test')

console.log(tasks)   // ['write', 'review', 'ship']
console.log(updated) // ['write', 'test', 'ship']

The arguments work like splice(): start index, delete count, then items to insert. To remove items without inserting, see how to remove an item from an array.

with()

with() replaces one item at a given index. It returns a new array.

const colors = ['red', 'green', 'blue']
const updated = colors.with(1, 'yellow')

console.log(colors)  // ['red', 'green', 'blue']
console.log(updated) // ['red', 'yellow', 'blue']

Negative indexes work too. colors.with(-1, 'purple') replaces the last item.

When to use them

My advice is to reach for these methods whenever you work with data you did not create yourself. A function that sorts an array passed in as an argument should not change that array.

If you need to mutate on purpose, the old methods still work. For most cases, returning a copy is safer. Read more about JavaScript arrays to see the full list of methods.

Lesson completed