
Old JavaScript code is painful to read. I recently went back to a project I'd built in 2019 and genuinely struggled to understand what 20-line functions were doing. The same logic today would be 5 lines using optional chaining, nullish coalescing, and destructuring.
Modern JavaScript (ES2020 and beyond) added features that aren't just syntactic sugar — they actually eliminate entire categories of bugs. Optional chaining alone saved me from probably three null-reference crashes in production code this year.
Here are the specific patterns I now use every day that make JavaScript significantly cleaner and less error-prone.

JavaScript Operators & Methods Comparison
Here is a summary of the modern operators and utility methods we will review:
| Operator / Method | introduced ES Version | Primary Use Case | Fallback / Behavior |
|---|---|---|---|
Optional Chaining (?.) | ES2020 | Safely reads nested object fields | Returns undefined if parent is null/undefined |
Nullish Coalescing (??) | ES2020 | Provides default values | Falls back only on null or undefined |
| Promise.allSettled() | ES2020 | Runs concurrent async promises | Returns array of results, even if some fail |
| Array.prototype.flatMap() | ES2019 | Maps and flattens array arrays | Flattens up to depth of 1 |
Set Spread ([...new Set(arr)]) | ES2015 | Deduplicates array items in 1 line | De-duplicates primitive values in O(N) |

1. Optional Chaining (?.)
Stop crashing your application when trying to read nested object properties that might be null or undefined.
// Old Way (Verbose and hard to scale)
let streetName = "Unknown";
if (user && user.address && user.address.street) {
streetName = user.address.street;
}// Modern Way (Clean, safe, short) let street = user?.address?.street ?? "Unknown";
// Also works on dynamic properties and function calls let firstHobby = user?.hobbies?.[0]; let profileData = user?.getProfileInfo?.();
2. Nullish Coalescing (??)
Traditionally, developers used the logical OR (||) operator to assign default values. However, || falls back on any falsy value, including empty strings "", boolean false, and the number 0, which often causes bugs in data tracking.
// Old Way (Logical OR - causes bug if count is 0)
let count = response.count || 10;
console.log(count); // Prints 10 even if response.count was 0!// Modern Way (Nullish Coalescing - preserves 0 and empty strings) let correctCount = response.count ?? 10; console.log(correctCount); // Prints 0 if response.count is 0
3. Object Destructuring with Renaming and Fallbacks
Extract properties from objects and rename them inline inside a single, clean line. You can also assign default values during destructuring.const user = { firstName: 'Suresh', age: 30 };// Rename firstName to 'name', and assign fallback to 'role' const { firstName: name, age, role = 'User' } = user;
console.log(name); // Suresh console.log(role); // User (Default applied)
4. One-Line Array Deduplication using Set
The fastest way to strip duplicate items from an array is combining theSet constructor with the spread operator.
const duplicateArray = [1, 2, 2, 3, 4, 4, 5];// Set removes duplicates; spread converts it back to an array const uniqueArray = [...new Set(duplicateArray)]; console.log(uniqueArray); // [1, 2, 3, 4, 5]
5. Parallel Async Handling with Promise.allSettled()
Using standardPromise.all() is risky because if a single promise fails, the entire batch rejects immediately, throwing away all other successful responses. Promise.allSettled() runs all promises concurrently and returns an array containing the status and value of each item.
const promises = [
fetch('/api/users'),
fetch('/api/broken-endpoint'), // Fails
fetch('/api/settings')
];const results = await Promise.allSettled(promises);
results.forEach((result) => { if (result.status === 'fulfilled') { console.log('Success:', result.value); } else { console.log('Error:', result.reason); } });
Frequently Asked Questions (FAQs)
#### Does optional chaining work in all browsers?
Yes, optional chaining (?.) and nullish coalescing (??) are fully supported in all modern browsers (Chrome, Safari, Firefox, Edge). For legacy browser support (like Internet Explorer), build tools like Babel will automatically compile these operators into standard ES5 if checks.
#### Is there a performance difference between standard loops and Set deduplication?
For small to medium arrays, the performance difference is negligible. However, [...new Set(arr)] runs in O(N) time complexity, which is significantly faster and cleaner than nested loop approaches (O(N^2)) when dealing with thousands of items.
#### Can I use optional chaining to write to properties?
No. Optional chaining is strictly for reading properties. You cannot use it on the left-hand side of an assignment operator (e.g. user?.address?.street = "New Street" is invalid and will throw a syntax error).
Final Thoughts
Mastering modern JavaScript is about writing code that is easy to read and difficult to break. By replacing bloated logic checks with clean operators like?. and ??, you can build safer web applications with fewer line counts.
