Lesson 33: Mastering JavaScript Optional Chaining (?.) with challenges!

Optional Chaining (?.
) is a JavaScript syntax feature that allows you to safely access nested object properties without having to manually check for nullish (null
or undefined
) values at each level.
✅ Basic Example
let user = {};
console.log(user?.address?.street); // undefined, no error
Instead of crashing with Cannot read property 'street' of undefined
, it gracefully returns undefined
.
✅ Real-World Example
let element = document.querySelector('.profile');
let html = element?.innerHTML; // undefined if the element doesn't exist
This avoids runtime errors when querying DOM elements that may not be present.
Visual Flow:
user?.address?.street
↓ ↓
undefined? stop here → return undefined
Optional chaining short-circuits evaluation as soon as it hits a null
or undefined
.
🔹 2. Fill Any Gaps
Let’s go deeper.
🧩 ?.
Is Not an Operator
It’s syntax, not a standalone operator like +
or &&
. That means you can’t use it arbitrarily in expressions like:
let result = user?.address + ' street'; // ❌ Might be undefined + ' street'
🧩 Works With:
Property access:
obj?.prop
Bracket notation:
obj?.[key]
Function/method calls:
obj.method?.()
Deletion:
delete obj?.prop
🧩 Does NOT Work With:
Assignments:
user?.name = "Alex"; // ❌ Syntax error
Declared references:
console.log(nonDeclaredVar?.something); // ❌ ReferenceError
🔥 Short-Circuiting Quirk
let count = 0;
null?.doSomething(count++); // count not incremented!
console.log(count); // 0
⚠️ Common Mistakes
Mistake | Explanation |
Overusing ?. | Hides bugs — e.g. if user should never be null, this masks it |
Using on undeclared vars | Still throws ReferenceError |
Misusing with assignment | obj?.prop = value is invalid |
🔹 3. Challenge Me Deeply
🟢 Basic
Access a nested property safely using optional chaining.
Use optional chaining to call a possibly undefined method.
Use optional chaining with bracket notation and dynamic keys.
🟡 Intermediate
Create a safe access utility function using optional chaining.
Write a function that logs the
.length
of a possibly-null array using optional chaining.Safely delete a deeply nested property from an object using optional chaining.
🔴 Advanced
Combine optional chaining with logical OR
||
to provide fallbacks.Use optional chaining inside a
.map()
call where objects might be incomplete.Refactor a deeply nested property access chain of 5+ levels using optional chaining.
Safely call a method with optional chaining and pass arguments from another optional chain.
🎯 Brain-Twister
- What will the following return and why?
let obj = {
method: () => null
};
console.log(obj.method?.().doesNotExist?.());
🔹 4. Interview-Ready Questions
❓ Concept Questions
What does optional chaining do internally?
What’s the difference between
?.
and&&
?Why does
user?.address.street
still throw ifuser
is not declared?
🧠 Scenario Questions
Given a JSON object from an API, how would you safely access a deeply nested optional property?
Refactor legacy code with multiple
&&
checks using optional chaining.
🛠️ Debugging Questions
- A dev uses
user?.profile.name
, butname
is undefined even thoughprofile
exists. What’s wrong?
✅ Best Practices
✅ Do This | ❌ Avoid This |
Use ?. when something is optional by logic | Blindly chaining everything |
Validate that the root variable is declared | Using it without declaring first |
Combine with default values (?? , ` |
🔹 5. Real-World Usage
✅ Frontend
React Components: Conditionally access props or DOM elements.
Form Validation:
form?.fields?.email?.value
API Integration: Access deeply nested data from APIs without checking every level.
const userName = apiResponse?.data?.user?.profile?.name ?? "Anonymous";
✅ Backend (Node.js)
- Reading from optional config objects or environment-specific data.
const dbPort = config?.database?.port ?? 3306;
✅ Frameworks
Vue 3 Composition API:
ref.value?.someProp
Next.js: Safe access to server-side props or headers
🔹 6. Remember Like a Pro
🧠 Mnemonic:
“If it might be empty, ask nicely with ?.
”
🧭 Mind Map
Optional Chaining
|
-------------------------
| | |
obj?.prop obj?.[key] obj.method?.()
|
Stops if undefined/null
🧾 Cheatsheet
// ✅ Safe Read
obj?.prop;
// ✅ Safe Function Call
obj.method?.(args);
// ✅ Safe Bracket Notation
obj?.[key];
// ✅ Safe Delete
delete obj?.prop;
// ❌ Invalid Assignment
obj?.prop = value;
🔹 7. Apply It in a Fun Way
🎮 Mini Project: “Safe Config Viewer”
Build a simple UI that:
Loads a nested config JSON (simulate API response).
Uses
?.
to safely access deep keys.Displays the path it took or returned
undefined
.
🛠 Steps:
Create a mock config JSON with optional values.
Build a form to input a path like
theme?.colors?.primary
.Parse and access it using
eval
or a custom resolver with?.
.Output the result.
Add fallback if
undefined
.
➕ Extend It:
Let users input multiple paths and compare outputs.
Add an option to see what would happen without optional chaining.
🧠 Bonus Value Pack
🚀 Open-Source Projects That Use It:
⚠️ Dev Mistakes
Using
?.
in expressions that rely on the result being not undefined (e.g.user?.profile.toUpperCase()
)Confusing
?.
with||
or??
🧩 Performance Tips
Optional chaining adds slight overhead — avoid in hot paths.
Don’t chain functions that aren’t memoized (e.g.,
getData()?.deepCall()?.another
)
🧰 Polyfill
Use Babel's @babel/plugin-proposal-optional-chaining for older browsers.
Subscribe to my newsletter
Read articles from manoj ymk directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
