JavaScript ES2024: New Features You Should Know
Explore the latest JavaScript ES2024 features including Array grouping, Promise.withResolvers, and more.
ES2024 Overview
ECMAScript 2024 (ES15) brings several exciting new features to JavaScript. These additions focus on developer ergonomics, making common patterns simpler and more intuitive.
Object.groupBy() and Map.groupBy()
One of the most anticipated features! Group array elements by a criterion without external libraries.
``javascript
const inventory = [
{ name: 'asparagus', type: 'vegetables', quantity: 5 },
{ name: 'bananas', type: 'fruit', quantity: 0 },
{ name: 'goat', type: 'meat', quantity: 23 },
{ name: 'cherries', type: 'fruit', quantity: 5 },
{ name: 'fish', type: 'meat', quantity: 22 }
];
const grouped = Object.groupBy(inventory, ({ type }) => type); console.log(grouped.fruit); // [{ name: 'bananas', ... }, { name: 'cherries', ... }]
// For Map-based grouping:
const mapGrouped = Map.groupBy(inventory, ({ quantity }) =>
quantity > 5 ? 'ok' : 'restock'
);
`
Promise.withResolvers()
Creates a Promise along with its resolve and reject functions, eliminating the "deferred" pattern boilerplate.
`javascript
// Before ES2024
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
// ES2024 const { promise, resolve, reject } = Promise.withResolvers();
// Useful for event-driven patterns
function waitForClick(element) {
const { promise, resolve } = Promise.withResolvers();
element.addEventListener('click', resolve, { once: true });
return promise;
}
`
ArrayBuffer Transfer
Transfer ownership of ArrayBuffer data for efficient memory management.
`javascript
const buffer = new ArrayBuffer(8);
const view = new Uint8Array(buffer);
view[0] = 42;
// Transfer to a new buffer (original becomes detached) const newBuffer = buffer.transfer(); console.log(buffer.byteLength); // 0 (detached) console.log(newBuffer.byteLength); // 8
// Resize during transfer
const resized = buffer.transferToFixedLength(16);
`
Well-Formed Unicode Strings
New methods to check and ensure well-formed Unicode strings.
`javascript
const valid = 'Hello World';
const invalid = 'Hello \uD800 World'; // lone surrogate
console.log(valid.isWellFormed()); // true console.log(invalid.isWellFormed()); // false
// Fix malformed strings
console.log(invalid.toWellFormed());
// 'Hello \uFFFD World' (replacement character)
`
RegExp v Flag (Unicode Sets)
Enhanced regular expressions with set notation and properties of strings.
`javascript
// Match characters in one set but not another
const regex = /[\p{Script=Greek}--[\u03C0]]/v;
// Set intersection const emojiButNotText = /[\p{Emoji}&&\p{ASCII}]/v;
// String properties
const multiCharEmoji = /\p{RGI_Emoji}/v;
`
Atomics.waitAsync()
Non-blocking waiting for shared memory operations, useful for web workers.
`javascript
const sharedBuffer = new SharedArrayBuffer(4);
const int32 = new Int32Array(sharedBuffer);
// In a worker - async wait (non-blocking) const result = Atomics.waitAsync(int32, 0, 0); result.value.then(status => { console.log('Woken up with status:', status); });
// In main thread - notify
Atomics.notify(int32, 0);
`
Practical Impact
Before ES2024 (grouping with reduce)
`javascript
const grouped = items.reduce((acc, item) => {
const key = item.category;
(acc[key] = acc[key] || []).push(item);
return acc;
}, {});
`After ES2024
`javascript
const grouped = Object.groupBy(items, item => item.category);
`Browser Support
Most ES2024 features are already available in modern browsers (Chrome 117+, Firefox 119+, Safari 17.4+). For older browsers, use Babel or core-js polyfills.
Summary
ES2024 brings practical improvements that reduce boilerplate and make common patterns more intuitive.
Object.groupBy()` alone eliminates one of the most frequently written utility functions. Start using these features today to write cleaner, more modern JavaScript.