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:

  1. Property Enumeration: Lodash extracts the own enumerable string and symbol properties of the source using keys or getAllKeys.
  2. Value Lookups: It iterates over these keys and retrieves the corresponding values from both the target and the source.
  3. Equivalence Checks: If a property value is a primitive, it evaluates the comparison using the SameValueZero algorithm. 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:

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:

Performance Optimizations in Deep Traversal

Evaluating dynamically generated structures introduces significant performance overhead if unoptimized. Lodash applies several strict low-level optimizations: