Modern Operators
Modern JavaScript includes operators that make common checks shorter and safer.
This lesson focuses on two very common ES6+ era features:
- optional chaining:
?. - nullish coalescing:
??
You may have seen these earlier.
Here, we connect them to modern JavaScript patterns.
The Problem With Deep Property Access
Objects often contain nested data.
const user = {
profile: {
address: {
city: "Delhi",
},
},
};
console.log(user.profile.address.city); // DelhiBut what if profile is missing?
const user = {};
console.log(user.profile.address.city); // TypeErrorJavaScript cannot read address from undefined.
Optional Chaining
Optional chaining lets you safely access nested properties.
const user = {};
console.log(user.profile?.address?.city); // undefinedIf the value before ?. is null or undefined, JavaScript stops and returns undefined.
This avoids a TypeError.
Optional Chaining With Methods
Optional chaining can also call a method only if it exists.
const user = {
greet() {
return "Hello";
},
};
console.log(user.greet?.()); // HelloIf the method is missing:
const user = {};
console.log(user.greet?.()); // undefinedThis is useful when a callback or method may not exist.
Optional Chaining With Arrays
You can use optional chaining with bracket access.
const users = [{ name: "Alice" }];
console.log(users[0]?.name); // Alice
console.log(users[1]?.name); // undefinedThis is helpful when an array item may not exist.
Nullish Coalescing
Nullish coalescing provides a fallback only when a value is null or undefined.
const name = null;
const displayName = name ?? "Guest";
console.log(displayName); // GuestThe operator is:
??Read it as:
Use the left value unless it is null or undefined.
Otherwise use the right value.?? vs ||
The || operator uses the right value for any falsy left value.
Falsy values include:
false0""nullundefinedNaN
Example:
const count = 0;
console.log(count || 10); // 10
console.log(count ?? 10); // 00 is falsy, so || uses 10.
But 0 is not null or undefined, so ?? keeps 0.
Preserving Valid Falsy Values
Use ?? when values like 0, false, or "" are valid.
const settings = {
volume: 0,
darkMode: false,
};
const volume = settings.volume ?? 50;
const darkMode = settings.darkMode ?? true;
console.log(volume); // 0
console.log(darkMode); // falseUsing || here would produce incorrect defaults.
Combining ?. and ??
Optional chaining and nullish coalescing work well together.
const user = {};
const city = user.profile?.address?.city ?? "Unknown";
console.log(city); // UnknownOptional chaining safely reads the nested value.
Nullish coalescing provides a fallback.
This is a very common modern JavaScript pattern.
Optional Chaining Does Not Hide All Errors
Optional chaining only protects against null or undefined at that point in the chain.
const user = {
profile: null,
};
console.log(user.profile?.name); // undefinedBut this still fails:
const user = null;
console.log(user.profile?.name); // TypeErrorWhy?
The optional chain starts at profile, but user itself is null.
Correct:
console.log(user?.profile?.name); // undefinedPut ?. where a value may be null or undefined.
Do Not Overuse Optional Chaining
Optional chaining is useful when missing data is expected.
But if a value should always exist, optional chaining can hide bugs.
const total = cart?.items?.length ?? 0;This is fine if cart may be missing.
But if cart should never be missing, a thrown error might reveal a real problem earlier.
Use optional chaining intentionally.
Best Practices
Use optional chaining for uncertain nested data:
const email = user.profile?.email;Use nullish coalescing for safe defaults:
const limit = options.limit ?? 10;Use ?? instead of || when 0, false, or "" should be preserved.
Combine them for common fallback patterns:
const city = user.address?.city ?? "Unknown";Do not use optional chaining to hide bugs in required data.
Common Mistakes
Mistake 1: Using || When 0 Is Valid
const quantity = 0;
const finalQuantity = quantity || 1;
console.log(finalQuantity); // 1Correct:
const finalQuantity = quantity ?? 1;Mistake 2: Starting Optional Chaining Too Late
const user = null;
console.log(user.profile?.name); // TypeErrorCorrect:
console.log(user?.profile?.name); // undefinedMistake 3: Overusing Optional Chaining
If data is required, optional chaining may hide a bug.
Use it when absence is expected.
Quick Check
What does this log?
const user = {};
console.log(user.profile?.email ?? "No email");It logs:
No emailWhat does this log?
const count = 0;
console.log(count ?? 10);It logs:
00 is not null or undefined.
Summary
Modern operators make safe access and defaults easier.
- Optional chaining
?.safely accesses values that may be missing. - It stops when the value before
?.isnullorundefined. - Nullish coalescing
??provides defaults fornullorundefined. ??preserves valid falsy values like0,false, and"".?.and??are often used together.- Use these operators intentionally, not to hide required data problems.