Bisexual Pride

ECMAScript 2023 (ES2023), also known as ECMAScript 14 (ES14), is scheduled for release in June. It brings six new array instance methods to the standard.

  1. Array.prototype.findLast()
  2. Array.prototype.findLastIndex()
  3. Array.prototype.toReversed()
  4. Array.prototype.toSorted()
  5. Array.prototype.toSpliced()
  6. Array.prototype.with()

Array.prototype.findLast()

The Array.prototype.findLast() method returns the value of the last element in the array that satisfies the provided testing function. If there is no such element, the method returns undefined. It complements the older Array.prototype.find() method, which returns the value of the first matching element.

const languages = ["C#", "Java", "JavaScript", "PHP", "Python", "Ruby"];
const lang = languages.findLast(lang => lang.startsWith("J"));
console.log(lang); // "JavaScript"

Array.prototype.findLastIndex()

The Array.prototype.findLastIndex() method returns the index of the last element in the array that satisfies the provided testing function. If there is no such element, the method returns -1. It complements the older Array.prototype.findIndex() method, which returns the index of the first matching element.

const languages = ["C#", "Java", "JavaScript", "PHP", "Python", "Ruby"];
const index = languages.findLastIndex(lang => lang.startsWith("J"));
console.log(index); // 2

Array.prototype.toReversed()

The Array.prototype.toReversed() method is the copying version of the older Array.prototype.reverse() method. Unlike the older method, it doesn’t mutate the array it’s called upon. It returns a new array. This is nice because you don’t have to create a copy of the array before reversing it, e.g. [...languages].reverse().

const languages = ["C#", "Java", "JavaScript", "PHP", "Python", "Ruby"];
const reversed = languages.toReversed();
console.log(languages); // ["C#", "Java", "JavaScript", "PHP", "Python", "Ruby"]
console.log(reversed); // ["Ruby", "Python", "PHP", "JavaScript", "Java", "C#"]

Array.prototype.toSorted()

The Array.prototype.toSorted() method is the copying version of the older Array.prototype.sort() method. Unlike the older method, it doesn’t mutate the array it’s called upon. It returns a new array. This is nice because you don’t have to create a copy of the array before sorting it, e.g. [...languages].sort().

const languages = ["Java", "Ruby", "Python", "C#", "PHP", "JavaScript"];
const sorted = languages.toSorted();
console.log(languages); // ["Java", "Ruby", "Python", "C#", "PHP", "JavaScript"]
console.log(sorted); // ["C#", "Java", "JavaScript", "PHP", "Python", "Ruby"]

Array.prototype.toSpliced()

The Array.prototype.toSpliced() method is the copying version of the older Array.prototype.splice() method. Unlike the older method, it doesn’t mutate the array it’s called upon. It returns a new array. This is nice because you don’t have to create a copy of the array before splicing it, e.g. [...languages].splice(2, 1).

const languages = ["C#", "Java", "JavaScript", "PHP", "Python", "Ruby"];
const spliced = languages.toSpliced(2, 1);
console.log(languages); // ["C#", "Java", "JavaScript", "PHP", "Python", "Ruby"]
console.log(spliced); // ["C#", "Java", "PHP", "Python", "Ruby"]

This method excites me because, in my opinion, it provides a more natural way to update state in UI libraries such as React. Before this method was introduced, you would probably use the Array.prototype.filter() method:

const [items, setItems] = useState([
{ id: "item-nSXV2tABU-OE6Z5hecroM", name: "Item 1" },
{ id: "item-SH6WM4JUMJbEhrGk4oBqz", name: "Item 2" },
{ id: "item-c5ov4S3CPDAKNrFn9SLtL", name: "Item 3" },
]);

function removeItem(id) {
const filtered = items.filter(item => item.id !== id);
setItems(filtered);
}

In my opinion, this process is more natural with the .toSpliced() method, because it’s closer to how you would remove an element from an array in vanilla JavaScript:

function removeItem(index) {
const splicedItems = items.toSpliced(index, 1);
setItems(splicedItems);
}

Here’s a demo you can play with. At the time of writing, it should work in Chrome 110, Edge 110, Opera 96, and Safari 16.3.

Array.prototype.with()

The Array.prototype.with() method is the copying version of using bracket notation to set the value of an element at a given index in an array. Unlike bracket notation, it doesn’t mutate the array it’s called upon. It returns a new array. This is nice because you can chain array methods while performing manipulations, without worrying about mutating the original array.

const languages = ["C#", "Java", "JavaScript", "PHP", "Python", "Ruby"];
const modified = languages.with(0, "C++");
console.log(languages); // ["C#", "Java", "JavaScript", "PHP", "Python", "Ruby"]
console.log(modified); // ["C++", "Java", "JavaScript", "PHP", "Python", "Ruby"]

Imagine you wanted to change one of the languages in the array before sorting it, without mutating the original array. Before the .with() method was introduced, you’d probably have to copy the array first, mutate the copy, then sort the copy:

const languages = ["Java", "Ruby", "Python", "C#", "PHP", "JavaScript"];
const sorted = [...languages];
sorted[3] = "C++";
sorted.sort();
console.log(languages); // ["Java", "Ruby", "Python", "C#", "PHP", "JavaScript"]
console.log(sorted); // ["C++", "Java", "JavaScript", "PHP", "Python", "Ruby"]

This becomes much more ergonomic using the .with() method, because you can just chain a call to the .sort() method:

const languages = ["Java", "Ruby", "Python", "C#", "PHP", "JavaScript"];
const sorted = languages.with(3, "C++").sort();
console.log(languages); // ["Java", "Ruby", "Python", "C#", "PHP", "JavaScript"]
console.log(sorted); // ["C++", "Java", "JavaScript", "PHP", "Python", "Ruby"]

Browser support

At the time of writing, the .findLast() and .findLastIndex() methods are supported in:

  • Chrome 97
  • Edge 97
  • Firefox 104
  • Opera 83
  • Safari 15.4

The .toReversed(), .toSorted(), .toSpliced(), and .with() methods are supported in:

  • Chrome 110
  • Edge 110
  • Opera 96
  • Safari 16.3

Note the lack of support in Firefox at the present time. You can find the full browser support information for these methods on Can I Use.