JavaScript ES2024: New Features You Should Know
Discover the latest JavaScript features in ES2024. From new array methods to improved async patterns, learn what's new in the JavaScript ecosystem.
JavaScript ES2024: New Features You Should Know
The JavaScript language continues to evolve with exciting new features in ES2024 (ES15). This article explores the most significant additions and how they can improve your development workflow.
New Array Methods
Array.prototype.with()
Create a new array with a single element changed:
const numbers = [1, 2, 3, 4, 5];
const updated = numbers.with(2, 10);
console.log(updated); // [1, 2, 10, 4, 5]
console.log(numbers); // [1, 2, 3, 4, 5] (original unchanged)
Array.prototype.toReversed()
Returns a new array with elements in reverse order:
const original = [1, 2, 3, 4, 5];
const reversed = original.toReversed();
console.log(reversed); // [5, 4, 3, 2, 1]
console.log(original); // [1, 2, 3, 4, 5] (unchanged)
Array.prototype.toSorted()
Create a new sorted array without mutating the original:
const names = ['Charlie', 'Alice', 'Bob'];
const sorted = names.toSorted();
console.log(sorted); // ['Alice', 'Bob', 'Charlie']
console.log(names); // ['Charlie', 'Alice', 'Bob'] (unchanged)
Array.prototype.toSpliced()
Non-mutating version of splice():
const fruits = ['apple', 'banana', 'cherry', 'date'];
const modified = fruits.toSpliced(1, 2, 'blueberry', 'coconut');
console.log(modified); // ['apple', 'blueberry', 'coconut', 'date']
console.log(fruits); // ['apple', 'banana', 'cherry', 'date'] (unchanged)
Enhanced String Methods
String.prototype.isWellFormed()
Check if a string contains well-formed Unicode:
const wellFormed = "Hello 👋";
const malformed = "Hello \uD800"; // Lone surrogate
console.log(wellFormed.isWellFormed()); // true
console.log(malformed.isWellFormed()); // false
String.prototype.toWellFormed()
Convert to well-formed Unicode string:
const malformed = "Hello \uD800 World";
const fixed = malformed.toWellFormed();
console.log(fixed); // "Hello � World" (with replacement character)
Object Grouping
Object.groupBy()
Group array elements by a key function:
const people = [
{ name: 'Alice', age: 25, department: 'Engineering' },
{ name: 'Bob', age: 30, department: 'Marketing' },
{ name: 'Charlie', age: 35, department: 'Engineering' },
{ name: 'Diana', age: 28, department: 'Marketing' }
];
const byDepartment = Object.groupBy(people, person => person.department);
console.log(byDepartment);
// {
// Engineering: [
// { name: 'Alice', age: 25, department: 'Engineering' },
// { name: 'Charlie', age: 35, department: 'Engineering' }
// ],
// Marketing: [
// { name: 'Bob', age: 30, department: 'Marketing' },
// { name: 'Diana', age: 28, department: 'Marketing' }
// ]
// }
Map.groupBy()
Similar to Object.groupBy() but returns a Map:
const byAgeGroup = Map.groupBy(people, person => {
return person.age < 30 ? 'young' : 'experienced';
});
console.log(byAgeGroup);
// Map {
// 'young' => [
// { name: 'Alice', age: 25, department: 'Engineering' },
// { name: 'Diana', age: 28, department: 'Marketing' }
// ],
// 'experienced' => [
// { name: 'Bob', age: 30, department: 'Marketing' },
// { name: 'Charlie', age: 35, department: 'Engineering' }
// ]
// }
Promise.withResolvers()
A new static method that returns an object with a promise and its resolve/reject functions:
const { promise, resolve, reject } = Promise.withResolvers();
// Use the promise
promise.then(value => console.log('Resolved:', value));
// Resolve from elsewhere
setTimeout(() => resolve('Hello from the future!'), 1000);
This is particularly useful for creating promises that need to be resolved from external contexts.
Atomics.waitAsync()
Non-blocking version of Atomics.wait():
const sharedBuffer = new SharedArrayBuffer(1024);
const sharedArray = new Int32Array(sharedBuffer);
// Non-blocking wait
const result = Atomics.waitAsync(sharedArray, 0, 0);
if (result.async) {
result.value.then(outcome => {
console.log('Wait completed:', outcome);
});
}
Regular Expression v Flag
Enhanced Unicode support in regular expressions:
// Unicode property escapes in character classes
const regex = /[\p{Script=Latin}&&\p{Letter}]/v;
console.log(regex.test('a')); // true
console.log(regex.test('α')); // false
// String literals in character classes
const emojiRegex = /[\q{👨💻|👩💻|🧑💻}]/v;
console.log(emojiRegex.test('👨💻')); // true
ArrayBuffer Transfer
Transfer ownership of ArrayBuffer between contexts:
const buffer = new ArrayBuffer(1024);
const view = new Uint8Array(buffer);
view[0] = 42;
// Transfer the buffer (becomes detached in current context)
const transferred = buffer.transfer();
console.log(buffer.byteLength); // 0 (detached)
console.log(transferred.byteLength); // 1024
Best Practices
- Use Non-Mutating Array Methods: Prefer
toSorted()
,toReversed()
, etc. for immutable operations - Leverage Object.groupBy(): Simplify data transformation and grouping operations
- Check Unicode Well-Formedness: Use
isWellFormed()
when dealing with user-generated content - Adopt Promise.withResolvers(): For complex promise orchestration scenarios
Browser Support
These features are rolling out across modern browsers:
- Chrome 117+ (most features)
- Firefox 118+ (most features)
- Safari 17+ (most features)
Always check current compatibility tables and consider polyfills for production use.
Conclusion
ES2024 brings practical improvements to JavaScript with a focus on immutability, better Unicode handling, and enhanced developer experience. These features make JavaScript code more predictable and easier to reason about, especially in functional programming paradigms.