Lodash _.isEqualWith() method
What you’ll learn
- How
_.isEqualWith(value, other, customizer)layers overrides onto deep equality. - When returning
undefineddelegates back to lodash defaults. - How explicit
true/falseresults short-circuit comparisons. - Patterns like tolerant string matching versus forcing rejection.
Prerequisites
You already understand _.isEqual basics and can write small comparator callbacks.
- You know deep equality cares about nested shapes, not only references.
- Try-it labs load lodash from the CDN.
Overview
Reach for _.isEqualWith when business rules diverge from lodash defaults: locale-aware strings, numeric tolerance, branded wrappers, or selectively ignoring volatile metadata fields.
Customizer hook
Inspect each compared pair before lodash decides.
undefined fallback
Return nothing to keep standard deep comparison for that pair.
Explicit vote
Return booleans to approve or veto equality immediately.
Syntax
_.isEqualWith(value, other, [customizer]) - value / other: values to compare (same role as in
_.isEqual). - customizer (optional):
(objValue, othValue [, index|key, object, other, stack])— returnundefinedto defer. - Returns:
trueif equivalent under custom rules; otherwisefalse.
Treat alternate greetings as equal
Official lodash pattern: treat "hello" and "hi" as interchangeable while other slots stay strict.
import isEqual from "lodash/isEqual";
import isEqualWith from "lodash/isEqualWith";
function isGreeting(value) {
return /^h(?:i|ello)$/.test(value);
}
function greetingCustomizer(objValue, othValue) {
if (isGreeting(objValue) && isGreeting(othValue)) {
return true;
}
}
var left = ["hello", "goodbye"];
var right = ["hi", "goodbye"];
console.log(
"withCustomizer: " + isEqualWith(left, right, greetingCustomizer) + "\n" + // true
"plainIsEqual: " + isEqual(left, right) // false
); Force false at the root pair
If the customizer returns false for the top-level arguments, lodash stops there even when structures match.
import isEqual from "lodash/isEqual";
import isEqualWith from "lodash/isEqualWith";
var a = { id: 1 };
var b = { id: 1 };
function alwaysRejectRoot() {
return false;
}
console.log(
"withoutCustomizer: " + isEqual(a, b) + "\n" + // true
"equalWithReject: " + isEqualWith(a, b, alwaysRejectRoot) // false
); Case-insensitive nested strings
Return booleans only for strings; return undefined elsewhere so nested objects still compare normally.
import isEqual from "lodash/isEqual";
import isEqualWith from "lodash/isEqualWith";
function ignoreCaseCustomizer(objValue, othValue) {
if (typeof objValue === "string" && typeof othValue === "string") {
return objValue.toLowerCase() === othValue.toLowerCase();
}
}
console.log(
"caseInsensitive: " +
isEqualWith({ tag: "Hello" }, { tag: "hello" }, ignoreCaseCustomizer) +
"\n" + // true
"plainIsEqual: " +
isEqual({ tag: "Hello" }, { tag: "hello" }) // false
); 📋 _.isEqualWith vs related checks
| API | Matches |
|---|---|
_.isEqualWith(a, b, fn) | Deep equality with per-pair overrides from fn. |
_.isEqual(a, b) | Same deep walk without custom overrides. |
_.isMatchWith(a, b, fn) | Partial structural match with optional customizer. |
JSON.stringify | Fragile string hack; keys/order/types often diverge from real semantics. |
Pitfalls to avoid
Over-broad customizers
Returning true too eagerly can hide real mismatches—narrow conditions (types, keys, tags).
Heavy work per pair
Deep trees invoke customizers often; keep regex, parsing, and allocation out of tight loops.
undefined vs missing return
Explicit return undefined reads clearly versus falling through accidentally with mixed branches.
❓ FAQ
Summary
- Purpose: extend deep equality with domain-specific comparison hooks.
- Remember: only return booleans when overriding; otherwise return
undefined. - Next: explore more on Lodash _.isError().
When your customizer returns undefined, lodash falls back to normal deep comparison for that pair (with your customizer still available deeper in the walk). Any other return value is coerced with !!, so false forces inequality even if structures match.
6 people found this page helpful
