The Rise of ES2025: What’s New in JavaScript?
Today, We will learn about The Rise of ES2025: What’s New in JavaScript? In this tutorial, I will give you The Rise of ES2025: What’s New in JavaScript? Dive into the latest features introduced in ES2025, including improved array methods, pattern matching, and more. These updates promise cleaner and more efficient code for developers.
The Rise of ES2025: What’s New in JavaScript?
- Simplifying Deep Property Access with Optional Chaining (?.) in JavaScript
- Nullish Coalescing Operator (??) in JavaScript
- BigInt: Handling Large Integers in JavaScript
- globalThis: A Universal Global Object in JavaScript
- String.prototype.matchAll(): Powerful Regex Matching in JavaScript
- Promise.allSettled(): Handling Multiple Promises in JavaScript
- String.prototype.at(): Indexing Made Easier in JavaScript
- Error.prototype.cause: Better Error Context in JavaScript
1. Simplifying Deep Property Access with Optional Chaining (?.) in JavaScript
The ?. operator short-circuits and returns undefined if the part of the object you’re trying to access doesn’t exist. This prevents runtime errors and keeps your code clean and concise. It can be used for:
Example: Practical Usage
const user = {
name: "John Doe",
profile: {
contact: {
email: "[email protected]",
},
},
};
// Accessing email safely using optional chaining
console.log(user?.profile?.contact?.email); // Output: "[email protected]"
// Attempting to access a missing property
console.log(user?.profile?.contact?.phone); // Output: undefined
// Providing a fallback value using the nullish coalescing operator
console.log(user?.profile?.contact?.phone ?? "Phone number not available");
// Output: "Phone number not available"
2. Nullish Coalescing Operator (??) in JavaScript
The nullish coalescing operator (??), introduced in ECMAScript 2020, provides a default value when the first operand is null or undefined. Unlike the logical OR (||) operator, it doesn’t treat falsy values like 0, false, or “” as nullish, making it ideal for handling truly “missing” values.
Example: Practical Usage
const userInput = null;
const defaultValue = "Default Text";
const result = userInput ?? defaultValue;
console.log(result); // Output: "Default Text"
const validInput = "";
console.log(validInput ?? defaultValue); // Output: ""
In this example:
- null and undefined trigger the fallback value (defaultValue).
- Falsy values like “” or 0 don’t trigger the fallback, maintaining their intended meaning.
3. BigInt: Handling Large Integers in JavaScript
Introduced in ES2020, BigInt is a numeric primitive that enables JavaScript to represent and manipulate integers beyond the Number type’s safe limit (2^53 – 1). With BigInt, you can perform precise calculations on extremely large numbers without losing accuracy.
Example: Practical Usage
// Creating BigInt values
const largeNumber = 9007199254740991n; // Adding 'n' makes it a BigInt
const anotherLargeNumber = BigInt("123456789012345678901234567890");
// Performing operations
console.log(largeNumber + 1n); // Output: 9007199254740992n
console.log(anotherLargeNumber * 2n); // Output: 246913578024691357802469135780n
// Mixing BigInt with Number throws an error
// console.log(largeNumber + 1); // TypeError: Cannot mix BigInt and Number
In this example:
- Use the suffix n or BigInt() to create BigInt values.
- BigInt is not directly interchangeable with Number; explicit conversion is required.
4. globalThis: A Universal Global Object in JavaScript
Introduced in ES2020, globalThis is a standardized way to access the global object across all JavaScript environments, including browsers (window), Node.js (global), and Web Workers. It ensures consistent code without needing environment-specific checks.
Example: Practical Usage
// Accessing global properties
console.log(globalThis.setTimeout); // Works in all environments
console.log(globalThis.Math.PI); // Output: 3.141592653589793
// Defining a global variable
globalThis.myGlobalValue = "Hello, world!";
console.log(globalThis.myGlobalValue); // Output: "Hello, world!"
5. String.prototype.matchAll(): Powerful Regex Matching in JavaScript
Introduced in ES2020, the matchAll() method returns an iterator containing all matches of a regular expression in a string, including capturing groups. Unlike match(), it allows iteration over matches and supports detailed data extraction for complex patterns.
Example: Practical Usage
const text = "Order ID: 123, Order ID: 456, Order ID: 789";
const regex = /Order ID: (\d+)/g;
const matches = text.matchAll(regex);
for (const match of matches) {
console.log(`Found: ${match[0]}, ID: ${match[1]}`);
}
// Output:
// Found: Order ID: 123, ID: 123
// Found: Order ID: 456, ID: 456
// Found: Order ID: 789, ID: 789
In this example:
- matchAll() returns an iterator, not an array so that you can loop over matches with for…of.
- It’s particularly useful for accessing capturing groups in regex patterns.
6. Promise.allSettled(): Handling Multiple Promises in JavaScript
Introduced in ES2020, Promise.allSettled() returns a promise that resolves after all promises in an array have settled (either resolved or rejected). It provides detailed results for each promise, making it ideal for scenarios where you need the outcome of all promises, regardless of their success or failure.
Example: Practical Usage
const promises = [
Promise.resolve("Success 1"),
Promise.reject("Error 1"),
Promise.resolve("Success 2"),
];
Promise.allSettled(promises).then((results) => {
results.forEach((result, index) => {
if (result.status === "fulfilled") {
console.log(`Promise ${index + 1} resolved with:`, result.value);
} else {
console.log(`Promise ${index + 1} rejected with:`, result.reason);
}
});
});
// Output:
// Promise 1 resolved with: Success 1
// Promise 2 rejected with: Error 1
// Promise 3 resolved with: Success 2
In this example:
- Unlike Promise.all(), it doesn’t fail fast on rejections.
- Ensures you get the status and result of every promise, making it useful for error-tolerant workflows.
7. String.prototype.at(): Indexing Made Easier in JavaScript
Introduced in ES2022, the at() method allows you to retrieve the character at a specific index in a string. It supports negative indices, making it convenient to access characters from the end without calculating the length.
Example: Practical Usage
const str = "JavaScript";
// Access characters using positive indices
console.log(str.at(0)); // Output: "J"
// Access characters using negative indices
console.log(str.at(-1)); // Output: "t"
console.log(str.at(-3)); // Output: "i"
// Handling out-of-range indices
console.log(str.at(20)); // Output: undefined
console.log(str.at(-20)); // Output: undefined
In this example:
- Simplifies working with strings, especially when accessing characters from the end.
- Provides a modern, readable alternative to charAt() and manual length calculations.
8. Error.prototype.cause: Better Error Context in JavaScript
Introduced in ES2022, the cause property on Error objects allows you to specify the underlying cause of an error, making it easier to trace and understand complex error chains.
Example: Practical Usage
try {
const causeError = new Error("Database connection failed");
const mainError = new Error("Unable to fetch data");
mainError.cause = causeError;
throw mainError;
} catch (err) {
console.log(err.message); // Output: "Unable to fetch data"
console.log(err.cause.message); // Output: "Database connection failed"
}
In this example:
- Provides more informative error handling by linking errors to their causes.
- Helps with debugging by maintaining a clear context of the error chain.