How Lodash _.find Handles Array-Like Objects
This article explains how Lodash's _.find method
processes array-like objects when their .length property or
numeric indices are non-continuous, sparse, or invalid. Lodash relies on
internal validation functions—primarily isArrayLike and
isLength—to decide whether to treat an object as an indexed
list or as a standard key-value map. Understanding this branching logic
clarifies how missing indices and non-standard .length
values are evaluated during predicate execution.
The isArrayLike
Decision Branch
Before iterating, _.find invokes baseFind,
which routes the collection through Lodash’s internal iteration pipeline
(derived from baseEach). The collection is inspected using
isArrayLike:
function isArrayLike(value) {
return value != null && typeof value != 'function' && isLength(value.length);
}The isLength helper verifies that
value.length is a typeof number, greater than or equal to
0, equal to Math.floor(value.length), and less
than or equal to Number.MAX_SAFE_INTEGER
(9007199254740991).
How Lodash iterates depends entirely on whether the object satisfies these conditions:
Case 1:
Valid .length with Non-Continuous (Sparse) Indices
If an object possesses a valid .length (for example,
{ 0: 'a', 2: 'c', length: 3 }), isArrayLike
evaluates to true.
Lodash executes an optimized standard ascending index loop:
for (var i = 0; i < length; i++) {
var value = collection[i];
if (predicate(value, i, collection)) {
return value;
}
}Because it uses direct index access (collection[i])
rather than checking for key existence via
Object.prototype.hasOwnProperty or in:
- Sequential Access: Lodash increments
istrictly by1from0tolength - 1. - Missing Index Handling: Any gap where an index is
missing directly evaluates to
undefined. - Predicate Execution: The provided predicate
callback receives
undefined, the current indexi, and the collection itself. - Early Exit: If the predicate returns truthy for
undefined(e.g., checking_.isUndefined), iteration stops immediately at that gap and returnsundefined. Otherwise, it advances to the next numerical index.
Case 2: Broken or
Non-Continuous .length Values
If an object lacks a valid .length entirely (such as an
undefined, negative, floating-point, or non-numeric
.length), isLength returns false,
causing isArrayLike to return false.
When isArrayLike fails:
- Lodash routes the object into its standard object iterator
(
baseForOwn). - It extracts property names using
keys(object), which collects all enumerable own string-keyed properties. - It iterates over these actual enumerable keys rather than a
0tolength - 1sequence. - Gaps are skipped because only existing properties are yielded.
- The non-standard
lengthproperty itself is treated like any other regular property and passed to the predicate along with its value and key name.