Replace Lodash _.get with Optional Chaining

This article explains how to replace Lodash's _.get method using modern JavaScript's native optional chaining (?.) and nullish coalescing (??) operators. You will learn the direct syntactic equivalents for nested property access, dynamic keys, array indexing, and default fallback values without requiring external utility libraries.

The Basic Equivalent

In Lodash, _.get safely retrieves deeply nested values without throwing a TypeError if an intermediate reference is null or undefined. In modern JavaScript (ES2020+), the syntactic equivalent is the optional chaining operator (?.).

Lodash:

const street = _.get(user, 'address.street');

Modern JavaScript:

const street = user?.address?.street;

If user or address is null or undefined, the expression short-circuits and evaluates to undefined instead of throwing an error.


Adding Default Values

Lodash allows passing a third argument as a fallback default value if the resolved value is undefined. The modern JavaScript equivalent combines optional chaining with the nullish coalescing operator (??).

Lodash:

const role = _.get(user, 'profile.role', 'guest');

Modern JavaScript:

const role = user?.profile?.role ?? 'guest';

The nullish coalescing operator (??) ensures that fallback values are only applied when the result is null or undefined, preserving falsy but valid values like 0, false, or "".


Dynamic Properties and Array Indexing

Lodash supports both string path notation and array notation for accessing array items and dynamic object keys. Modern JavaScript achieves this using bracket notation with optional chaining (?.[]).

Array Elements

Lodash:

const firstItem = _.get(order, 'items[0].name');
// or
const firstItem = _.get(order, ['items', 0, 'name']);

Modern JavaScript:

const firstItem = order?.items?.[0]?.name;

Dynamic Keys

Lodash:

const dynamicKey = 'settings';
const theme = _.get(user, [dynamicKey, 'theme']);

Modern JavaScript:

const dynamicKey = 'settings';
const theme = user?.[dynamicKey]?.theme;

Safe Function and Method Calls

While Lodash provides _.result for invoking functions that might be present on a path, modern JavaScript extends optional chaining directly to function calls using ?.().

Modern JavaScript:

// Safely calls calculateTotal if it exists; otherwise evaluates to undefined
const total = order?.calculateTotal?.();

Key Difference: Runtime String Paths

Optional chaining is a syntax feature, meaning property names must be known at write time or explicitly passed via bracket notation. It does not parse dot-delimited strings dynamically created at runtime (e.g., "data.nested.key").

If dynamic string paths determined at runtime are required, use Array.prototype.reduce:

const getByPath = (obj, path, defaultValue) => {
  const travel = (regexp) =>
    String.prototype.split
      .call(path, regexp)
      .filter(Boolean)
      .reduce((res, key) => (res !== null && res !== undefined ? res[key] : undefined), obj);
  
  const result = travel(/[,[ \].]+?/);
  return result === undefined || result === obj ? defaultValue : result;
};

For all standard access patterns, object?.path?.to?.property ?? defaultValue completely replaces the need for Lodash's _.get.