Lodash isMatch: Partial Deep Comparison Explained

The Lodash _.isMatch method performs a partial deep comparison between a target object and a source object to determine if the target contains equivalent property values. Unlike a full deep equality check, it only evaluates the properties present on the source object, ignoring any extra keys on the target. This article details how this deep partial comparison evaluates nested objects, handles arrays, tests primitive values, and behaves in practical JavaScript applications.

Understanding the Syntax and Core Concept

The method uses the following signature:

_.isMatch(object, source)

The comparison is termed "partial" because the target object is permitted to have additional properties that are absent in source. As long as every property defined in source exists in object with an equivalent value, _.isMatch returns true.

What Makes the Comparison "Deep"?

A shallow comparison only evaluates top-level properties (similar to checking object[key] === source[key]). In contrast, _.isMatch recursively traverses nested data structures:

  1. Nested Objects: When a property value in source is an object, _.isMatch does not compare references. Instead, it enters that nested object and recursively checks its keys against the corresponding nested object in the target.
  2. Arrays: When traversing arrays, _.isMatch treats them as objects with numeric keys. It checks whether the target array contains equivalent values at the same indices defined in the source array.
  3. Primitive Values: At the leaf nodes of the traversal, values are compared using the SameValueZero algorithm (similar to strict equality ===, but treating NaN as equal to NaN).

Practical Example

Consider the following scenario with deeply nested user data:

const user = {
  id: 101,
  name: "Alex",
  profile: {
    role: "Admin",
    preferences: {
      theme: "dark",
      notifications: { email: true, sms: false }
    }
  },
  tags: ["developer", "editor"]
};

// Partial match on deeply nested properties
const source = {
  profile: {
    preferences: {
      theme: "dark"
    }
  },
  tags: ["developer"]
};

console.log(_.isMatch(user, source)); // true

In this example:

Key Behavioral Nuances