Lodash _.has() method
What you’ll learn
- How
_.has(object, path)checks whether an own property exists at a nested path. - Why existing falsey values still return
true. - How string paths, bracket notation, and array paths behave.
- When to use
_.hasIn(),_.get(), or nativeObject.hasOwn()instead.
Prerequisites
You should know the difference between reading a value and checking whether a property exists. _.has answers existence, not truthiness.
- Own properties only: inherited prototype properties return
falsewith_.has. - Falsey values still exist:
null,undefined,0,false, and""all count if the property is present. - Path syntax matters: use array paths for keys that literally contain dots or brackets.
Overview
_.has walks a path and returns true when every segment exists as an own property on the current object. It is useful when you need to distinguish "this property is present with a falsey value" from "this property is missing entirely".
Existence, not value
A present property whose value is undefined still returns true.
Own properties only
Prototype properties do not count. Use _.hasIn when they should.
Nested path support
Use dotted strings, bracket strings, or arrays for deeply nested checks.
Syntax
_.has(object, path) - object: the object to inspect.
nullorundefinedreturnsfalse. - path: a string path (
"a.b[0]") or array path (["a", "b", 0]). - Returns:
trueif the full path exists as own properties; otherwisefalse.
Check a nested own property
Use _.has when you need a boolean before deciding whether to read or render a nested value.
import has from "lodash/has";
const sample = {
user: {
name: "John Doe",
address: {
city: "Exampleville",
postalCode: "12345"
}
},
isActive: true
};
has(sample, "user.address.postalCode");
// -> true
has(sample, "user.address.country");
// -> false
has(sample, "isActive");
// -> true Falsey values still count as existing
_.has is not a truthiness test. It returns true when the property is present, even if the stored value is falsey.
import has from "lodash/has";
const settings = {
theme: null,
retries: 0,
enabled: false,
label: "",
explicit: undefined
};
has(settings, "theme"); // -> true
has(settings, "retries"); // -> true
has(settings, "enabled"); // -> true
has(settings, "label"); // -> true
has(settings, "explicit"); // -> true
has(settings, "missing"); // -> false Array paths and inherited properties
Array paths preserve literal keys and avoid ambiguity. Inherited properties are deliberately excluded by _.has.
import has from "lodash/has";
import hasIn from "lodash/hasIn";
const proto = { inheritedFlag: true };
const record = Object.create(proto);
record.items = [{ id: 1 }];
record["x.y"] = { z: 42 };
has(record, "items[0].id");
// -> true
has(record, ["x.y", "z"]);
// -> true
has(record, "x.y.z");
// -> false (looks for record.x.y.z)
has(record, "inheritedFlag");
// -> false
hasIn(record, "inheritedFlag");
// -> true 📋 _.has vs related checks
| Topic | _.has | _.hasIn | _.get | Object.hasOwn() |
|---|---|---|---|---|
| Nested path support | Yes | Yes | Yes | No |
| Own properties | Yes | Yes | Reads them | Yes |
| Inherited properties | No | Yes | Reads them | No |
| Returns value | No, boolean | No, boolean | Yes | No, boolean |
| Falsey values | Still true if present | Still true if present | Returns the value | Still true if present |
Use _.has for nested own-property checks, _.hasIn for own-or-inherited checks, _.get when you need the value, and Object.hasOwn() for one-level native checks.
Pitfalls to avoid
Do not treat _.has like an if (value) check
A property containing false, 0, or null can still be a valid, intentional value.
Inherited properties return false
This is by design. Use _.hasIn only when inherited properties are part of the expected API.
Dotted keys need array paths
"x.y.z" means three segments. Use ["x.y", "z"] if "x.y" is one literal key.
Validate dynamic paths
If a path comes from a request or query string, compare it against an allow-list before checking internal object shapes.
❓ FAQ
Summary
- Purpose: check whether an own property exists at a path.
- Remember:
_.hasis not a truthiness check and does not count inherited properties. - Next: Lodash _.hasIn(), _.get(), or the official Lodash docs for _.has.
_.has checks whether the path exists as an own property. It returns true even when the value is undefined, null, false, 0, or an empty string.
5 people found this page helpful
