Lodash _.get() method

Beginner
⏱️ 7 min read
📚 Updated: May 2026
🎯 3 Code examples
🚀 3 Try-it labs
Lodash

What you’ll learn

  • How _.get(object, path, [defaultValue]) safely reads nested values, even when intermediate segments are missing.
  • The three path formats: dotted string, bracket notation, and array of segments—and when each is required.
  • Why null, 0, and false are not replaced by the default value.
  • When to reach for native optional chaining (?.) instead.

Prerequisites

Comfortable with property access (obj.a.b) and basic JSON shapes. Familiarity with optional chaining helps but isn’t required.

  • undefined vs. nullish: the default only fires for undefined. null survives.
  • Dynamic vs. static paths: use _.get when the path is computed at runtime; otherwise consider native ?..
  • Array form for tricky keys: keys containing dots or brackets require the array path form.

Overview

_.get resolves a path segment by segment. If any segment along the way is null or undefined, the traversal stops and the default value (or undefined) is returned—no thrown TypeError. It accepts the object as null or undefined too, which makes it safe for partial API responses.

Crash-free reads

No Cannot read properties of undefined—missing segments produce the default instead.

Three path formats

Dotted string, bracket notation, or an array of segments. Mix them freely.

Default only for undefined

null, 0, "", false all pass through unchanged.

Syntax

javascript
_.get(object, path, [defaultValue])
  • object: source to read from. May be null or undefined.
  • path: a string ("a.b[0].c") or an array (["a", "b", 0, "c"]).
  • defaultValue (optional): returned when the resolved value is undefined.
  • Returns: the resolved value, or defaultValue, or undefined.
1

Safe nested reads with a default

The classic use case: pull a deeply-nested value, falling back to a sensible default when any intermediate segment is missing.

javascript
import get from "lodash/get";

const profile = {
  user: {
    details: { name: "John Doe", age: 30 },
    preferences: { theme: "dark" }
  }
};

get(profile, "user.details.name", "Unknown");
// -> "John Doe"

get(profile, "user.contact.email", "no-email@example.com");
// -> "no-email@example.com"
//    user.contact is undefined, so the default is used.

get(profile, "user.details.age");
// -> 30   (no default needed)
Try it Yourself
2

Three path formats & array indexing

Dotted string, bracket string, and array path all describe the same traversal—but only the array form is safe when a key contains dots or special characters.

javascript
import get from "lodash/get";

const data = {
  users: [
    { id: 1, name: "Ada" },
    { id: 2, name: "Linus" }
  ],
  "x.y": { z: 42 }            // literal key contains a dot
};

get(data, "users[0].name");   // -> "Ada"   (bracket notation)
get(data, "users.1.name");    // -> "Linus" (dotted, numeric segment)
get(data, ["users", 1, "id"]);// -> 2       (array path, numeric index)

get(data, "x.y.z");           // -> undefined
//   ^ wrong: splits into ["x", "y", "z"]; "x" doesn't exist.

get(data, ["x.y", "z"]);      // -> 42
//   ^ correct: array form preserves the dotted key literally.
Try it Yourself
3

null survives the default

A subtle one: the default fires only for undefined. If the API explicitly returned null, you keep null. Same goes for 0, "", and false.

javascript
import get from "lodash/get";

const flags = {
  email: null,
  retries: 0,
  notes: "",
  archived: false
};

get(flags, "email", "default@example.com");
// -> null   (default IS NOT used)

get(flags, "retries", 3);   // -> 0
get(flags, "notes",   "n/a"); // -> ""
get(flags, "archived", true); // -> false

get(flags, "missing", "default@example.com");
// -> "default@example.com"   (path is undefined, default kicks in)
Try it Yourself

📋 _.get vs ?. vs _.at

Topic_.getOptional chaining ?._.at
Crash-safeYesYesYes
Dynamic pathYes (string or array)No (static literal)Yes (array of paths)
Default valueFor undefined onlyUse ?? manuallyNo default; returns an array
Multiple pathsOne per callOne per expressionMany at once
Runtime costFunction callZero (native)Function call + allocation

Use optional chaining for known shapes and hot paths. Use _.get when the path is data-driven or you want the default in one shot. Use _.at when you need several values at once.

Pitfalls to avoid

null

null blocks the default

The default only fires for undefined. To also replace null, combine with ??: _.get(obj, "x", fallback) ?? fallback.

Dots in keys

Dotted keys break string paths

If a key literally contains a dot, the string form splits it. Use an array path: ["x.y", "z"].

Untrusted input

Don’t feed user input to _.get blindly

Dynamic paths sourced from a query string can read __proto__ or other internals. Validate against an allow-list.

Hot loops

Costlier than ?.

String parsing and a function call per read add up. In hot loops with a known shape, prefer native optional chaining.

❓ FAQ

Only when the resolved value is strictly undefined. If the path resolves to null, 0, false, or an empty string, _.get returns that value—the default is ignored.
Three: a dotted string like 'a.b.c', a string with bracket notation like 'a[0].b', or an array of segments like ['a', 0, 'b']. The array form is mandatory when a key itself contains dots or square brackets.
Yes. Numeric segments index into arrays: _.get({ items: [{ id: 1 }] }, 'items[0].id') returns 1, and _.get(arr, [0, 'id']) works the same way.
Optional chaining is a built-in operator with a static, compile-time path. _.get accepts dynamic path strings and arrays, and it has a built-in defaultValue argument. Pick optional chaining for known paths, _.get when the path is computed or comes from configuration.
Yes. _.get reads via standard property access, so inherited properties along the prototype chain are resolved like any other property read.
_.get returns the defaultValue (or undefined if you didn't pass one). It does not throw, which is a common reason to reach for it over hand-written chains of && checks.

Summary

  • Purpose: safely read a value at a path, returning a default when the path is missing.
  • Remember: default fires only for undefined; null/0/false/"" survive. Use array paths for keys with dots.
  • Next: Lodash _.has(), _.set(), or the official Lodash docs for _.get.
Did you know?

The defaultValue argument is only used when the path resolves to undefined. A path that resolves to null, 0, false, or "" keeps that value—Lodash will not substitute the default.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful