How Lodash _.property Safely Fetches Object Paths
The _.property method in Lodash is a higher-order
function that generates an accessor function for retrieving the value
located at a specified path of an object. This article explores how
_.property securely traverses object properties, transforms
path notations into standard tokens, and guards against runtime
exceptions such as accessing properties on null or
undefined.
At its core, _.property(path) returns a new function
that accepts an object and safely returns the value at the defined
path. Rather than immediately accessing nested attributes,
it decouples the path definition from the target object, making it ideal
for mapping, filtering, or sorting collections without throwing
unexpected runtime errors.
The security and reliability of _.property stem from
Lodash's internal resolution mechanics, primarily driven by two core
functions: toPath and baseGet.
1. Path Normalization with
toPath
Before an object can be traversed, the input path must
be parsed. Lodash accepts property paths as single keys, arrays of keys,
or strings with dot and bracket notations (such as
'user.addresses[0].city').
The internal toPath utility evaluates the path:
- If the input is already an array, it retains the segments.
- If the input is a symbol or non-string primitive, it handles it directly.
- If the input is a string, a specialized regular expression breaks
the string into an array of individual property keys (e.g.,
['user', 'addresses', '0', 'city']).
Lodash caches these parsed paths internally to optimize repeated executions while ensuring malicious string formatting does not break runtime parsing.
2. Iterative Traversal via
baseGet
Native JavaScript encounters a
TypeError: Cannot read properties of undefined when
attempting to access a nested child of a nonexistent parent (e.g.,
obj.user.address when user is
undefined).
Lodash avoids this using an iterative traversal algorithm found in
baseGet. Instead of resolving the entire chain at once, the
returned function loops through the normalized array of keys:
function baseGet(object, path) {
path = castPath(path, object);
let index = 0;
const length = path.length;
while (object != null && index < length) {
object = object[toKey(path[index++])];
}
return (index && index == length) ? object : undefined;
}3. Null and Undefined Short-Circuiting
The while loop checks object != null on
each iteration, which evaluates to false for both
null and undefined using loose equality. If
any intermediary property in the path is missing or non-object:
- The traversal immediately terminates.
- The loop does not advance to subsequent keys.
- The function exits cleanly and returns
undefined.
This short-circuit behavior provides complete type safety when reading unvalidated or heterogeneous API payloads.
4. Avoiding Prototype Poisoning
Because _.property is strictly a read operation that
traverses existing references using property accessors rather than
modifying object descriptors or assigning keys, it poses no risk of
prototype pollution during data extraction. It safely skips inaccessible
keys without modifying standard object prototypes, producing a
predictable, side-effect-free accessor.