JavaScript's === compares objects and arrays by reference, and Object.assign only copies top-level properties. Lodash gives you explicit control over both comparison depth and copy depth.
Compare by value, not by reference
_.isEqual performs a deep comparison and returns true when two values are structurally equivalent, even if they are different object instances:
var a = { x: 1, nested: { y: 2 } };
var b = { x: 1, nested: { y: 2 } };
a === b;
// => false
_.isEqual(a, b);
// => true_.isEqual supports arrays, array-like objects, plain objects, Date, RegExp, Map, Set, and typed arrays. Function values and non-enumerable properties are not compared.
Custom comparisons
Pass a customizer to _.isEqualWith when you need a comparison rule isEqual doesn't provide:
function isGreeting(value) {
return /^h(?:i|ello)$/.test(value);
}
function customizer(objValue, othValue) {
if (isGreeting(objValue) && isGreeting(othValue)) {
return true;
}
// returning undefined falls back to the default comparison
}
_.isEqualWith(['hello', 'goodbye'], ['hi', 'goodbye'], customizer);
// => trueChoose a clone depth
_.clone copies only the top level of an object or array; nested objects are shared by reference with the original. cloneDeep recursively clones every nested value, so the copy is fully independent.
var original = { x: 1, nested: { y: 2 } };
var shallow = _.clone(original);
var deep = _.cloneDeep(original);
shallow.nested === original.nested;
// => true — mutating shallow.nested also changes original.nested
deep.nested === original.nested;
// => false — mutating deep.nested leaves original.nested untouched_.clone only when you know a value has no nested objects or arrays, or when sharing nested references is intentional. Otherwise a later mutation through the shallow copy silently changes the original.Use _.cloneDeepWith when part of the structure needs custom copy logic — for example, values cloneDeep cannot represent, such as DOM nodes or class instances with private state.
Related methods
| Task | Method |
|---|---|
| Deep-compare two values | isEqual |
| Deep-compare with a custom rule | isEqualWith |
| Shallow copy | clone |
| Deep copy | cloneDeep |
| Deep copy with custom logic | cloneDeepWith |
| Check whether a value matches a partial shape | isMatch |
Next steps
- See every type-checking method —
isPlainObject,isNil,isArrayLike, and more — in Lang methods. - Merging deeply nested objects has its own rules; see
mergeandmergeWithin the Object reference.