By the end of this tutorial, you’ll build reusable partial-match predicates with Lodash’s _.matches() and use them in filter, find, and conditional checks.
01
Core Syntax
_.matches(source) returns a predicate.
02
Partial Match
Only listed keys are compared.
03
Deep Compare
Nested objects match recursively.
04
Filter & Find
Pair with collection methods.
05
Shorthand
Object literals in _.filter.
06
vs conforms
Values vs predicate functions.
Fundamentals
What Is _.matches()?
_.matches() creates a predicate function for partial deep comparison. You describe a pattern object (source); the returned function checks whether another object matches every key you listed—nothing more. Extra fields on the target object are ignored.
💡
Beginner tip — partial, not exact
_.matches({ role: 'admin' }) matches { name: 'Bob', role: 'admin', active: true } because role matches. Bob’s other properties are not required in the pattern.
If you have ever written _.filter(users, { age: 30 }), you already used matches semantics—Lodash converts that object shorthand internally. Explicit _.matches() lets you store and reuse the same predicate.
Foundation
📝 Syntax
Pass a pattern object; receive a predicate function:
javascript
_.matches(source)
Syntax Rules
source — plain object describing properties and values to match.
Return value — a function (object) => boolean.
Partial — only keys in source are checked; extra target keys are allowed.
Deep — nested plain objects in source are compared recursively.
One-off check — use _.isMatch(object, source) when you do not need a reusable predicate.
Store const isJohnAt30 = _.matches({ age: 30, name: 'John' }) when the same predicate runs in multiple places. See also _.iteratee().
Example 6 — Conditional logic
Call the predicate directly in an if statement.
javascript
const user = { name: "John", age: 30 };
const isAdmin = _.matches({ role: "admin" });
if (isAdmin(user)) {
console.log("User is an admin");
} else {
console.log("User is not an admin");
}
// User is not an admin — no role property
📤 Console output:
User is not an admin
Missing keys fail the match
If a key in the pattern is missing on the object (or undefined without matching), the predicate returns false.
Compare
📋 _.matches vs related patterns
Topic
_.matches
_.isMatch
_.conforms
_.isEqual
Returns
Predicate fn
Boolean now
Validator fn
Boolean now
Compares
Fixed values
Fixed values
Predicate fns
Full deep equality
Scope
Partial keys
Partial keys
Listed keys
Entire value
Best for
Filter / find
One-off test
Type / range rules
Clone compare
Shorthand
_.filter(a, { k: v })
N/A
N/A
N/A
🧠 How _.matches() Works
1
Capture pattern
Lodash stores the source object you pass in.
Setup
2
Return predicate
The new function closes over that pattern for reuse.
Factory
3
Partial deep compare
On each call, every key in source is compared—recursively for nested objects.
Execute
=
✅
true or false
All listed keys match → true. Any mismatch → false.
Important
📝 Notes
Matching is partial—only keys in source matter; extra target properties are fine.
Nested patterns use nested objects, not dot-path strings like 'user.name'.
_.filter(arr, { k: v }) and _.filter(arr, _.matches({ k: v })) behave the same.
Use _.isMatch(obj, pattern) for a single immediate check without storing a predicate.
For custom validation logic per field (types, ranges), use _.conforms() instead.
Store _.matches(pattern) when the same filter runs in multiple places
Use object shorthand for one-off _.filter / _.find calls
Model nested data with nested pattern objects
Pair with _.find, _.some, and _.reject
Use _.isMatch for single boolean checks
❌ Don’t
Expect full object equality—use _.isEqual for that
Use dot strings inside matcher objects for nested paths
Assume missing pattern keys pass automatically—they must match values
Use matches when each field needs a custom predicate—use conforms
Mutate source after creating the predicate if you rely on stable rules
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about _.matches()
Use these points when matching objects in Lodash.
5
Core concepts
🔎01
Predicate
Pattern → fn.
Basics
📄02
Partial
Listed keys only.
Mechanics
📈03
Deep
Nested objects.
Structure
📊04
Filter
Collection ops.
Practical
→05
conforms
Custom rules.
Compare
❓ Frequently Asked Questions
_.matches(source) returns a predicate function. When you call it with an object, it returns true if that object partially matches source—a deep comparison on every key listed in source. Extra properties on the object do not fail the match.
_.isEqual(a, b) checks full deep equality between two values. _.matches(source) checks only the keys you list in source—partial match. An object can have many other properties and still match.
Yes. _.filter(users, { age: 30 }) uses the same partial-match rules as _.filter(users, _.matches({ age: 30 })). _.matches() is for storing and reusing the predicate.
Yes. Nested source objects are compared deeply. For example, _.matches({ user: { name: 'John' } }) matches { id: 1, user: { name: 'John', age: 30 } } because the listed nested keys match.
_.matches() compares values with partial deep equality (object patterns). _.conforms() runs custom predicate functions per key—useful for type checks, ranges, and regex tests instead of fixed values.
Use it to filter or find records by fixed field values, build reusable search predicates, and express object-shape checks readably in _.filter, _.find, _.some, and conditional logic.
Did you know?
When you pass a plain object to _.filter or _.find, Lodash converts it through the same matching rules as _.matches(). Explicit _.matches(pattern) is most valuable when you name and reuse that predicate across your codebase.