How Lodash _.matches Evaluates Deep Objects
This article explores how the _.matches method in the
Lodash JavaScript library performs deep, structural evaluations of
nested and dynamically cloned objects. By examining Lodash's internal
matching engine—specifically baseMatches,
baseIsMatch, and baseIsEqual—we analyze how
the library traverses complex object graphs, handles reference
differences inherent to cloned data, detects circular references, and
enforces partial deep equivalence with high performance.
The Core
Mechanism: baseMatches and baseIsMatch
When _.matches(source) is invoked, Lodash creates a
predicate function designed to determine whether a given target object
contains equivalent property values to those of the source.
Internally, this function wraps baseMatches, which captures
the source object in a closure.
Rather than executing a shallow reference equality check
(===), the predicate delegates evaluation to
baseIsMatch. This function systematically compares the
target object against the source:
- Property Enumeration: Lodash extracts the own
enumerable string and symbol properties of the
sourceusingkeysorgetAllKeys. - Value Lookups: It iterates over these keys and retrieves the corresponding values from both the target and the source.
- Equivalence Checks: If a property value is a
primitive, it evaluates the comparison using the
SameValueZeroalgorithm. If the property value is a complex structure (such as an object or array), it triggers recursive deep matching.
Evaluating Dynamically Cloned and Deep Structures
When deep structures are dynamically cloned (for instance, via
_.cloneDeep or structured cloning), their memory references
diverge. A standard identity check
(target.prop === source.prop) fails for any non-primitive
leaf or branch.
Lodash overcomes this through recursive structural decomposition:
- De-referencing and Recursion: When encountering
nested plain objects or arrays,
baseIsMatchbypasses pointer identity. It recursively calls itself or passes the nodes down tobaseIsEqualconfigured with specific comparison flags (COMPARE_PARTIAL_FLAG). - Partial Containment (Superset Matching): The
evaluation is non-strict regarding property counts. The target object is
permitted to contain extra properties not present in the
source. As long as every path specified insourceexists intargetand resolves to an equivalent value, the match evaluates totrue. - Type and Tag Validation: Cloned structures maintain
prototype tags (such as
[object Object]or[object Array]). Lodash validates these internal tags viagetTagto ensure that an array is not falsely matched against a plain object with numeric keys.
Circular References and Memory Safety
Dynamic and deeply cloned graphs frequently introduce circular references. Without safeguards, recursive evaluation would trigger a stack overflow.
Lodash handles this natively through an internal Stack
cache:
- Before traversing deeper into an object branch, Lodash records the
current
sourceandtargetpair in a stack structure (implemented as a fast array for small sets or aMapfor larger sets). - If the traversal encounters a reference to an object already registered in the stack, it halts infinite recursion and confirms reference alignment across the cycle.
- Once the branch evaluation resolves, the entries are cleared or marked to maintain minimal memory overhead.
Performance Optimizations in Deep Traversal
Evaluating dynamically generated structures introduces significant performance overhead if unoptimized. Lodash applies several strict low-level optimizations:
- Single-Property Fast Path: If the
sourceobject contains only a single primitive property, Lodash skips the overhead ofbaseIsMatchand uses an optimized inline comparison. - Direct Property Access: Instead of relying on
dynamic prototype lookups, it utilizes direct property access checks
(
hasOwnProperty) to avoid traversing the prototype chain of the target unless explicitly configured. - Bail-Out Checks: The comparison terminates
immediately (
return false) at the first mismatched leaf node, preventing unnecessary traversals of sibling branches in deeply nested trees.