DEV Community

Manoj Swami
Manoj Swami

Posted on • Updated on

10 Must-Know JavaScript ES15 (2024) Features for Modern Development

JavaScript continues to evolve, and with the release of ECMAScript 2024 (ES15), developers have access to even more powerful features. In this article, we'll explore 10 must-know ES15 features that will enhance your modern JavaScript development. We'll provide examples, outputs, and comparisons to previous versions to help you understand and adopt these new features.

1. Array.prototype.groupBy()

The groupBy() method allows you to group elements in an array based on a given callback function.

// ES15
const people = [
  { name: 'Alice', age: 30 },
  { name: 'Bob', age: 25 },
  { name: 'Charlie', age: 30 },
  { name: 'David', age: 25 },
];

const groupedByAge = people.groupBy(person => person.age);
console.log(groupedByAge);

// Output:
// {
//   25: [{ name: 'Bob', age: 25 }, { name: 'David', age: 25 }],
//   30: [{ name: 'Alice', age: 30 }, { name: 'Charlie', age: 30 }]
// }

// Previous approach (ES6+)
const groupedByAgeOld = people.reduce((acc, person) => {
  if (!acc[person.age]) {
    acc[person.age] = [];
  }
  acc[person.age].push(person);
  return acc;
}, {});
Enter fullscreen mode Exit fullscreen mode

The new groupBy() method simplifies the process of grouping array elements, making the code more readable and concise.

2. Array.prototype.with()

The with() method creates a new array with a specific index updated, without modifying the original array.

// ES15
const fruits = ['apple', 'banana', 'cherry'];
const newFruits = fruits.with(1, 'blueberry');

console.log(fruits);    // Output: ['apple', 'banana', 'cherry']
console.log(newFruits); // Output: ['apple', 'blueberry', 'cherry']

// Previous approach (ES6+)
const newFruitsOld = [...fruits.slice(0, 1), 'blueberry', ...fruits.slice(2)];
Enter fullscreen mode Exit fullscreen mode

The with() method provides a more intuitive way to create a new array with a single element changed, improving code readability.

3. Array.prototype.toSorted()

The toSorted() method returns a new sorted array without modifying the original array.

// ES15
const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
const sortedNumbers = numbers.toSorted();

console.log(numbers);        // Output: [3, 1, 4, 1, 5, 9, 2, 6]
console.log(sortedNumbers);  // Output: [1, 1, 2, 3, 4, 5, 6, 9]

// Previous approach (ES6+)
const sortedNumbersOld = [...numbers].sort();
Enter fullscreen mode Exit fullscreen mode

This method allows for easy sorting without the need to create a copy of the array manually.

4. Array.prototype.toReversed()

Similar to toSorted(), the toReversed() method returns a new reversed array without modifying the original array.

// ES15
const letters = ['a', 'b', 'c', 'd'];
const reversedLetters = letters.toReversed();

console.log(letters);           // Output: ['a', 'b', 'c', 'd']
console.log(reversedLetters);   // Output: ['d', 'c', 'b', 'a']

// Previous approach (ES6+)
const reversedLettersOld = [...letters].reverse();
Enter fullscreen mode Exit fullscreen mode

This method provides a cleaner way to reverse an array without mutating the original.

5. Array.prototype.toSpliced()

The toSpliced() method creates a new array with some elements removed and/or replaced without modifying the original array.

// ES15
const colors = ['red', 'green', 'blue', 'yellow'];
const newColors = colors.toSpliced(1, 2, 'purple', 'orange');

console.log(colors);    // Output: ['red', 'green', 'blue', 'yellow']
console.log(newColors); // Output: ['red', 'purple', 'orange', 'yellow']

// Previous approach (ES6+)
const newColorsOld = [...colors.slice(0, 1), 'purple', 'orange', ...colors.slice(3)];
Enter fullscreen mode Exit fullscreen mode

This method simplifies the process of creating a new array with specific elements replaced or removed.

6. Object.groupBy()

Similar to Array.prototype.groupBy(), Object.groupBy() allows grouping of an iterable's elements into an object.

// ES15
const inventory = [
  { name: 'asparagus', type: 'vegetable' },
  { name: 'banana', type: 'fruit' },
  { name: 'goat', type: 'meat' },
  { name: 'cherries', type: 'fruit' },
  { name: 'fish', type: 'meat' }
];

const groupedInventory = Object.groupBy(inventory, ({ type }) => type);
console.log(groupedInventory);

// Output:
// {
//   vegetable: [{ name: 'asparagus', type: 'vegetable' }],
//   fruit: [{ name: 'banana', type: 'fruit' }, { name: 'cherries', type: 'fruit' }],
//   meat: [{ name: 'goat', type: 'meat' }, { name: 'fish', type: 'meat' }]
// }

// Previous approach (ES6+)
const groupedInventoryOld = inventory.reduce((acc, item) => {
  if (!acc[item.type]) {
    acc[item.type] = [];
  }
  acc[item.type].push(item);
  return acc;
}, {});
Enter fullscreen mode Exit fullscreen mode

This method provides a more straightforward way to group elements from an iterable into an object.

7. Promise.withResolvers()

Promise.withResolvers() returns an object with a promise and its associated resolve and reject functions.

// ES15
const { promise, resolve, reject } = Promise.withResolvers();

promise.then(value => console.log('Resolved:', value))
       .catch(error => console.log('Rejected:', error));

// Resolve the promise
resolve('Success!');

// Output: Resolved: Success!

// Previous approach (ES6+)
let resolveOld, rejectOld;
const promiseOld = new Promise((res, rej) => {
  resolveOld = res;
  rejectOld = rej;
});
Enter fullscreen mode Exit fullscreen mode

This new method simplifies the creation of promises with externally controlled resolution or rejection.

8. String.prototype.isWellFormed() and String.prototype.toWellFormed()

These methods help handle strings with potentially ill-formed UTF-16 code unit sequences.

// ES15
const wellFormed = 'Hello, 世界';
const illFormed = 'Hello, \uD800World';

console.log(wellFormed.isWellFormed());  // Output: true
console.log(illFormed.isWellFormed());   // Output: false

console.log(wellFormed.toWellFormed());  // Output: "Hello, 世界"
console.log(illFormed.toWellFormed());   // Output: "Hello, �World"

// Previous approach
// There was no built-in way to check or ensure well-formed strings
Enter fullscreen mode Exit fullscreen mode

These methods provide a standardized way to check and ensure well-formed UTF-16 strings.

9. Symbol.metadata

The Symbol.metadata property allows you to associate metadata with a symbol.

// ES15
const mySymbol = Symbol('mySymbol', { description: 'A custom symbol' });
console.log(mySymbol.description);  // Output: "A custom symbol"
console.log(mySymbol.metadata);     // Output: { description: 'A custom symbol' }

// Previous approach
// Metadata couldn't be directly associated with symbols
Enter fullscreen mode Exit fullscreen mode

This feature allows for more descriptive and informative symbol creation.

10. RegExp 'v' Flag

The new 'v' flag for RegExp enables set notation and properties of strings.

// ES15
const regex = /[\p{ASCII}&&\p{Lowercase}]/v;
console.log(regex.test('a'));  // Output: true
console.log(regex.test('A'));  // Output: false
console.log(regex.test('ñ'));  // Output: false

// Previous approach
// Set notation and properties of strings were not available in RegExp
Enter fullscreen mode Exit fullscreen mode

This new flag enhances the power and flexibility of regular expressions in JavaScript.

Conclusion

These 10 ES15 features bring significant improvements to JavaScript, making code more readable, efficient, and powerful. By adopting these new features, you can enhance your modern JavaScript development and write cleaner, more expressive code. Keep exploring and experimenting with these new additions to stay at the forefront of JavaScript development!

Top comments (0)