Technology · JavaScript

Intermediate

JavaScript Optional Chaining

Access nested properties safely with optional chaining and pair it with nullish coalescing for defaults.

TL;DR
  1. 01Access nested properties safely with the ?. operator.
  2. 02Provide fallback values for null using the ?? operator.
  3. 03Short-circuit chains the moment a value is nullish.

Optional Chaining Basics

  • Use ?. to read a nested property without throwing when a parent is missing.
    const user = { profile: null };
    console.log(user.profile?.email); // undefined, no error
    
  • Compare this to plain dot access, which throws a TypeError on a null parent.
    console.log(user.profile.email); // TypeError: Cannot read properties of null
    
  • Chain multiple ?. together to guard against several possibly-missing levels.
    const data = {};
    console.log(data.user?.address?.city); // undefined
    
  • Optional chaining works the same for deeply nested API response shapes.
    const city = response?.data?.user?.address?.city;
    
  • Mix ?. with regular dot access once you're sure a value exists.
    console.log(user.profile?.settings.theme); // safe up to settings, then normal access
    

Optional Method and Array Access

  • Use ?.() to call a method only if it actually exists on the object.
    const obj = {};
    obj.greet?.(); // does nothing, no error
    
  • This is useful for optional callback props in component-style code.
    function handleClick(onClick) {
      onClick?.(); // calls onClick only if it was provided
    }
    
  • Use ?.[index] to safely access array items or computed keys.
    const arr = null;
    console.log(arr?.[0]); // undefined
    
  • Combine bracket and dot chaining when working with dynamic data shapes.
    console.log(data?.items?.[0]?.name);
    
  • Optional chaining on arrays prevents errors when an API returns null instead of an empty array.
    const list = response?.results ?? [];
    list.forEach(item => console.log(item));
    

Nullish Coalescing for Defaults

  • Use ?? to supply a fallback only when the left side is null or undefined.
    const name = user.name ?? 'Anonymous';
    
  • Unlike ||, ?? keeps falsy-but-valid values like 0 or an empty string.
    const count = 0;
    console.log(count ?? 10); // 0
    console.log(count || 10); // 10, probably wrong here
    
  • Pair ?. and ?? together for safe access plus a sensible default in one line.
    const theme = user.settings?.theme ?? 'light';
    
  • Use ??= to assign a default only if the variable is currently null or undefined.
    let config = {};
    config.timeout ??= 3000;
    console.log(config.timeout); // 3000
    
  • Avoid mixing ?? directly with && or || without parentheses, since JavaScript forbids it.
    // const x = a || b ?? c; // SyntaxError
    const x = (a || b) ?? c; // valid with explicit grouping
    

Short-Circuiting Behavior

  • Evaluation stops the instant a ?. link finds null or undefined.
    function getEmail() {
      console.log('called');
      return 'a@b.com';
    }
    const user = null;
    user?.getEmail(); // "called" never logs, short-circuited
    
  • Function calls after a short-circuit point never execute, which avoids unwanted side effects.
    obj?.save?.(logChange()); // logChange() still runs, save?.() does not, if obj is null
    
  • The whole chained expression resolves to undefined once short-circuited, not null.
    console.log(null?.a?.b); // undefined, even though we started with null
    
  • Optional chaining short-circuits independently at each ?., not the entire statement at once.
    const result = a?.b.c?.d; // only guards at the two ?. points, not the plain .c access
    
  • Combine short-circuiting with ?? to build defensive code that never throws on missing data.
    function getCityOrDefault(user) {
      return user?.address?.city ?? 'Unknown city';
    }
    
Tips
  1. 01Combine ?. with ?? to safely read a deep property and supply a sensible default in a single readable expression.
  2. 02Use optional chaining on method calls with ?.() when a function might not exist on the object yet.
  3. 03Reach for nullish coalescing instead of the logical OR operator whenever zero or an empty string are valid values.
Warnings
  1. 01Optional chaining only guards against null and undefined, not other falsy values like 0 or an empty string.
  2. 02Overusing ?. everywhere can hide real bugs by silently swallowing errors that should surface during development.
  3. 03The || operator treats 0, empty strings, and false as missing, which often produces wrong defaults compared to ??.
FAQ
JavaScript GeneratorsJavaScript Prototypal Inheritance