Optional Chaining & Nullish Operators
Safe property access with ?., nullish coalescing with ??, nullish assignment ??=, and logical assignment — eliminating null checks from modern JavaScript.
What it is, in plain English: Optional chaining (?.) lets you read a property deep in an object chain without checking if each level exists — if any part is null or undefined, the expression short-circuits and returns undefined instead of throwing. The nullish coalescing operator (??) returns the right side only when the left side is null or undefined — unlike || which also triggers on 0, '', and false.
Safer code with fewer null checks
Two of the most common bugs in JavaScript involve null and undefined:
trying to access a property on something that doesn't exist, and using || for defaults
when 0 or "" should be valid values.
Three operators fix both problems cleanly.
?. — Optional chaining
Read a deeply nested property without crashing if something in the chain is missing.
const order = {
id: 1,
customer: {
name: "Alice",
address: {
city: "Mumbai"
}
}
};
// Without ?. — you need a chain of checks:
const city1 = order && order.customer && order.customer.address
&& order.customer.address.city;
// With ?. — one clean expression:
const city2 = order?.customer?.address?.city;
console.log(city2); // "Mumbai"
// If any step is missing — returns undefined, no crash:
console.log(order?.billing?.address?.city); // undefined
// Without ?.: TypeError: Cannot read properties of undefined// ?. on method calls:
const user = { getName: () => "Bob" };
console.log(user.getName?.()); // "Bob"
console.log(user.getEmail?.()); // undefined (method doesn't exist — no crash)
// ?. on array access:
const first = null;
console.log(first?.[0]); // undefined (not: TypeError: Cannot read properties of null)?? — Nullish coalescing (the better default operator)
Use ?? instead of || when 0, "",
or false are valid values that should NOT trigger the default.
// The || problem:
function setVolume(vol) {
const volume = vol || 50; // BUG: volume=0 becomes 50!
console.log("Volume:", volume);
}
setVolume(0); // Volume: 50 ← wrong!
setVolume(80); // Volume: 80 ← correct
// The ?? fix:
function setVolumeFix(vol) {
const volume = vol ?? 50; // Only defaults when vol is null/undefined
console.log("Volume:", volume);
}
setVolumeFix(0); // Volume: 0 ← correct
setVolumeFix(80); // Volume: 80 ← correct
setVolumeFix(null); // Volume: 50 ← correct (null → use default)
setVolumeFix(undefined); // Volume: 50 ← correctCombining ?. and ??
const config = {
server: {
port: 0, // 0 is a valid port
timeout: null, // null means "not set"
}
};
const port = config?.server?.port ?? 3000; // 0 (not 3000 — 0 is valid)
const timeout = config?.server?.timeout ?? 5000; // 5000 (null → default)
const host = config?.server?.host ?? "localhost"; // "localhost" (undefined → default)
console.log(port, timeout, host); // 0 5000 "localhost"
Try It Yourself
Official Sources
- MDN Web Docs — Optional chaining (?.)
- MDN Web Docs — Nullish coalescing (??)
- MDN Web Docs — Nullish coalescing assignment (??=)
- ECMAScript 2024 — Optional Chaining (§13.5.7)
- TC39 Optional Chaining Proposal
The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.