The 5 most transformative JavaScript features from ES14

Last updated on April 06, 2024
The 5 most transformative JavaScript features from ES14

JavaScript has come a long way in the past 10 years with brand new feature upgrades in each one.

Still remember when we created classes like this?

function Car(make, model) {
  this.make = make;
  this.model = model;
}

// And had to join strings like this
Car.prototype.drive = function() {
  console.log("Vroom! This " + this.make +
    " " + this.model + " is driving!");
};

Yeah, a lot has changed!

Let's take a look at the 5 most significant features that arrived in ES14 (2023); and see the ones you missed.

1. toSorted()

Sweet syntactic sugar.

ES14's toSorted() method made it easier to sort an array and return a copy without mutation.

Instead of this:

const nums = [5, 2, 6, 3, 1, 7, 4];

const sorted = clone.sort();

console.log(sorted); // [1, 2, 3, 4, 5, 6, 7]

// ❌❌ Mutated
console.log(nums); // [1, 2, 3, 4, 5, 6, 7]

We now got to do this ✅:

const nums = [5, 2, 6, 3, 1, 7, 4];

// ✅ toSorted() prevents mutation
const sorted = nums.toSorted();

console.log(sorted);  // [1, 2, 3, 4, 5, 6, 7]

console.log(nums);  // [5, 2, 6, 3, 1, 7, 4]

toSorted() takes a callback for controlling sorting behavior - ascending or descending, alphabetical or numeric. Just like sort().

2. Array find from last

Searching from the first item isn't always ideal:

const tasks = [
    { date: '2017-03-05', name: '👟run a 5k' },
    { date: '2017-03-04', name: '🏋️lift 100kg' },
    { date: '2017-03-04', name: '🎶write a song' },
    // 10 million records...
    { date: '2024-04-24', name: '🛏️finally sleep on time' },
    { date: '2024-04-24', name: '📝1h writing with no breaks' },
];

const found = tasks.find((item) => item.date === '2024-03-25');
const foundIndex = tasks.findIndex((item) => item.date === '2024-03-25');

console.log(found); // { value: '2024-03-25', name: 'do 1000 pushups' }
console.log(foundIndex); // 9,874,910

You can easily see that it'll be much faster for me to search our gigantic list from the end instead of start.

const tasks = [
    { date: '2017-03-05', name: 'run a 5k' },
    { date: '2017-03-04', name: 'lift 100kg' },
    { date: '2017-03-04', name: 'write a song' },
    // 10 million records...
    { date: '2024-04-24', name: 'finally sleep on time' },
    { date: '2024-04-24', name: '1h writing with no breaks' },
];

// ✅ Much faster
const found = tasks.findLast((item) => item.date === '2024-03-25');
const foundIndex = tasks.findLastIndex((item) => item.date === '2024-03-25');

console.log(found); // { value: '2024-03-25', name: 'do 1000 pushups' }
console.log(foundIndex); // 9,874,910

And they're also times you MUST search from the end for your program work.

Like we want to find the last even number in a list of numbers, find and findIndex will be incredibly off.

const nums = [7, 14, 3, 8, 10, 9];

// ❌ gives 14, instead of 10
const lastEven = nums.find((value) => value % 2 === 0);

// ❌ gives 1, instead of 4
const lastEvenIndex = nums.findIndex((value) => value % 2 === 0);

console.log(lastEven); // 14
console.log(lastEvenIndex); // 1

And calling reverse() won't work either, even as slow as it would be:

const nums = [7, 14, 3, 8, 10, 9];

// ❌ Copying the entire array with the spread syntax before
// calling reverse()
const reversed = [...nums].reverse();

// correctly gives 10
const lastEven = reversed.find((value) => value % 2 === 0);

// ❌ gives 1, instead of 4
const reversedIndex = reversed.findIndex((value) => value % 2 === 0);

// Need to re-calculate to get original index
const lastEvenIndex = reversed.length - 1 - reversedIndex;

console.log(lastEven); // 10
console.log(reversedIndex); // 1
console.log(lastEvenIndex); // 4

So in cases like where the findLast() and findLastIndex() methods come in handy.

const nums = [7, 14, 3, 8, 10, 9];

// ✅ Search from end
const lastEven = nums.findLast((num) => num % 2 === 0);

// ✅ Maintain proper indexes
const lastEvenIndex = nums.findLastIndex((num) => num % 2 === 0);

console.log(lastEven); // 10
console.log(lastEvenIndex); // 4

This code is shorter and more readable. Most importantly, it produces the correct result.

3. toReversed()

Another new Array method to promote immutability and functional programming.

Before - with reverse() ❌:

const arr = [5, 4, 3, 2, 1];

const reversed = arr.reverse();

console.log(reversed); // [1, 2, 3, 4, 5]

// ❌ Original modified
console.log(arr); // [1, 2, 3, 4, 5]

Now - with toReversed() ✅:

const arr = [5, 4, 3, 2, 1];

const reversed = arr.toReversed();

console.log(reversed); // [1, 2, 3, 4, 5]

// ✅ No modification
console.log(arr); // [5, 4, 3, 2, 1]

I find these immutable methods awesome for constantly chaining methods over and over without worrying about the original variables:

// ✅ Results are independent of each other
const nums = [5, 2, 6, 3, 1, 7, 4];

const result = nums
    .toSorted()
    .toReversed()
    .map((n) => n * 2)
    .join();

console.log(result); // 14,12,10,8,6,4,2

const result2 = nums
    .map((n) => 1 / n)
    .toSorted()
    .map((n) => n.toFixed(2))
    .toReversed();

console.log(result2);
// [ '1.00', '0.50', '0.33', '0.25',
//   '0.20', '0.17', '0.14' ]

4. toSpliced()

Lovers of functional programming will no doubt be pleased with all these new Array methods.

This is the immutable counterpart of .splice():

const colors = ['red🔴', 'purple🟣', 'orange🟠', 'yellow🟡'];

// Remove 2 items from index 1 and replace with 2 new items

const spliced = colors.toSpliced(1, 2, 'blue🔵', 'green🟢');

console.log(spliced); // [ 'red🔴', 'blue🔵', 'green🟢', 'yellow🟡' ]

// Original not modified
console.log(colors); // ['red🔴', 'purple🟣', 'orange🟠', 'yellow🟡'];

5. Array with() method

with() is our way of quickly change an array element with no mutation whatsoever.

Instead of this usual way:

const arr = [5, 4, 7, 2, 1]

// Mutates array to change element
arr[2] = 3;

console.log(arr);  // [5, 4, 3, 2, 1]

ES14 now let us do this:

const arr = [5, 4, 7, 2, 1];

const replaced = arr.with(2, 3);

console.log(replaced);  // [5, 4, 3, 2, 1]

// Original not modified
console.log(arr);  // [5, 4, 7, 2, 1]

Final thoughts

They were other features but ES14 was all about easier functional programming and built-in immutability.

With the rise of React we've seen declarative JavaScript explode in popularity; it's only natural that more of them come baked into the language as sweet syntactic sugar.

Coding Beauty Assistant logo

Try Coding Beauty AI Assistant for VS Code

Meet the new intelligent assistant: tailored to optimize your work efficiency with lightning-fast code completions, intuitive AI chat + web search, reliable human expert help, and more.

See also