Lodash _.hasIn() method

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

What you’ll learn

  • How _.hasIn(object, path) checks for own and inherited properties at a nested path.
  • Why this lets it see class methods and other prototype-side properties that _.has() hides.
  • How to pick between _.hasIn, _.has, _.get, and the in operator.
  • The prototype-pollution caveat when paths come from user input.

Prerequisites

Comfortable with prototype-based inheritance in JavaScript. You should know what "own" vs "inherited" properties mean.

  • Includes inherited: properties from the prototype chain count, unlike with _.has.
  • Existence, not value: a present property with a falsey value still returns true.
  • Prototype pollution risk: never pass unvalidated user paths—they can match __proto__ chain entries.

Overview

_.hasIn walks the path segment by segment using normal property access. Each segment is resolved through the prototype chain, so methods on a class’s prototype or properties on a mixin all count. Use it for “does this work if I read it?” checks. Use _.has when you specifically need an own-property answer.

Walks the prototype chain

Inherited methods and properties return true, just like the in operator would.

Crash-safe traversal

If an intermediate segment is null or undefined, it returns false without throwing.

Existence, not truthiness

A path containing null, 0, or "" still returns true.

Syntax

javascript
_.hasIn(object, path)
  • object: the object to inspect. null or undefined returns false.
  • path: a string path ("a.b[0]") or array path (["a", "b", 0]).
  • Returns: true if the path resolves through own or inherited properties; otherwise false.
1

Check a nested path

For plain objects with no special prototype, _.hasIn and _.has behave identically. The win shows up the moment inheritance enters the picture.

javascript
import hasIn from "lodash/hasIn";

const sample = {
  user: {
    details: { name: "John Doe", age: 30 },
    role: "admin"
  },
  status: "active"
};

hasIn(sample, "user.details.age");     // -> true
hasIn(sample, "user.details.email");   // -> false
hasIn(sample, "status");               // -> true
hasIn(sample, "user.role");            // -> true
Try it Yourself
2

Inherited properties & class methods

This is the actual difference between _.hasIn and _.has. Methods on a class’s prototype live one level up the chain—_.hasIn sees them, _.has doesn’t.

javascript
import has from "lodash/has";
import hasIn from "lodash/hasIn";

class User {
  constructor(name) { this.name = name; }
  greet() { return "Hi " + this.name; }
}
const u = new User("Ada");

has(u,   "name");   // -> true   (own)
hasIn(u, "name");   // -> true   (own)

has(u,   "greet");  // -> false  (lives on User.prototype)
hasIn(u, "greet");  // -> true   (chain includes prototype)

has(u,   "toString");   // -> false  (Object.prototype)
hasIn(u, "toString");   // -> true
Try it Yourself
3

Falsey values & array paths

Existence is independent of value. Array paths are necessary when a key literally contains a dot or bracket.

javascript
import hasIn from "lodash/hasIn";

const config = {
  retries: 0,
  enabled: false,
  notes: "",
  items: [{ id: 1 }],
  "x.y": { z: 42 }
};

hasIn(config, "retries");        // -> true   (0 is still present)
hasIn(config, "enabled");        // -> true   (false is still present)
hasIn(config, "notes");          // -> true   ("" is still present)
hasIn(config, "items[0].id");    // -> true
hasIn(config, ["x.y", "z"]);     // -> true   (literal dotted key)
hasIn(config, "x.y.z");          // -> false  (splits into x.y.z)
hasIn(config, "missing");        // -> false
Try it Yourself

📋 _.hasIn vs related checks

Topic_.hasIn_.hasin operatorObject.hasOwn()
Nested pathsYesYesNoNo
Own propertiesYesYesYesYes
Inherited propertiesYesNoYesNo
Returns valueNo, booleanNo, booleanNo, booleanNo, boolean
Falsey valuesStill true if presentStill true if presentStill true if presentStill true if present

Reach for _.hasIn when inherited surface is part of the API. Use _.has when the answer should ignore the prototype chain. Use the native in operator or Object.hasOwn() for single-level checks where no path resolution is needed.

Pitfalls to avoid

Prototype

Inherited matches can be surprising

hasIn({}, "toString") is true because toString lives on Object.prototype. If that surprises you, use _.has.

Security

Risk with user-supplied paths

Because _.hasIn walks the prototype chain, a polluted Object.prototype can produce false positives. Validate paths against an allow-list.

Truthiness

Existence is not truthiness

A property whose value is false or 0 still satisfies _.hasIn. Don’t use it where you mean “is this enabled?”.

Dots in keys

Dotted keys need array paths

"x.y.z" means three segments. Use ["x.y", "z"] if "x.y" is one literal key.

❓ FAQ

It checks whether a path exists on the object, including inherited properties from the prototype chain. It does not care whether the resolved value is truthy.
Both accept nested paths and check existence. _.has only returns true for own properties; _.hasIn also returns true for properties inherited via the prototype chain.
Yes. Existence is independent of value. If the path exists with undefined, null, 0, false, or an empty string, _.hasIn returns true.
Yes. ES class methods live on the prototype, so _.hasIn(instance, 'methodName') returns true even though _.has would return false.
Dotted strings ("a.b[0]"), bracket-notation strings, and array paths (["a", "b", 0]). Use array paths when a key literally contains dots or brackets.
Not by itself. Because it walks the prototype chain, a polluted Object.prototype can cause _.hasIn to return true for paths that were never explicitly set. Validate dynamic paths and never expose them to user input without an allow-list.

Summary

Did you know?

_.hasIn walks the prototype chain just like a normal property lookup. That means inherited properties—including ones added to Object.prototype—will return true. Stick with _.has when only own properties should count.

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.

5 people found this page helpful