Comprehensive Guide to Comparing Objects in JavaScript
November 9, 2024
:89 :0
Object Comparison Methods in JavaScript
1. The instanceof
Operator
The instanceof
operator checks if an object is an instance of a particular constructor function by examining the prototype chain.
Syntax
object instanceof Constructor
Key Characteristics
- Returns
true
ifConstructor.prototype
exists in the object's prototype chain - Works only with reference types (objects), not primitive values
- Affected by prototype modifications
Examples
class Person {}
const john = new Person();
console.log(john instanceof Person); // true
console.log(john instanceof Object); // true
const arr = [1, 2, 3];
console.log(arr instanceof Array); // true
Limitations
// Doesn't work with primitives
console.log('test' instanceof String); // false
// Cross-realm issues (e.g., iframes)
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
console.log([] instanceof iframe.contentWindow.Array); // false
2. Object.keys() vs Object.entries()
Method | Returns | Use Case |
---|---|---|
Object.keys() | Array of property names | When you only need keys |
Object.entries() | Array of [key, value] pairs | When you need both keys and values |
Practical Examples
Using Object.keys()
const user = { name: 'Alice', age: 30 };
Object.keys(user).forEach(key => {
console.log(`${key}: ${user[key]}`);
});
// Output:
// name: Alice
// age: 30
Using Object.entries()
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}
// Same output as above
3. Deep Object Comparison with Lodash
Lodash's _.isEqual()
performs deep equality comparison, making it ideal for comparing complex objects.
Basic Usage
const _ = require('lodash');
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
console.log(_.isEqual(obj1, obj2)); // true
Advanced Techniques
- Partial Comparison
const partialCompare = (obj1, obj2, keys) =>
_.isEqual(_.pick(obj1, keys), _.pick(obj2, keys));
console.log(partialCompare(
{ a: 1, b: 2, c: 3 },
{ a: 1, b: 4, c: 3 },
['a', 'c']
)); // true
- Custom Comparator
function customizer(objValue, othValue) {
if (_.isNumber(objValue) && _.isNumber(othValue)) {
return Math.abs(objValue - othValue) < 0.5;
}
}
console.log(_.isEqualWith(
{ x: 1.2, y: 2 },
{ x: 1.4, y: 2 },
customizer
)); // true
Performance Considerations
Method | Time Complexity | Best For |
---|---|---|
instanceof | O(1) | Prototype checks |
Object.keys | O(n) | Simple objects |
_.isEqual | O(n) | Deep comparison |
Native Alternatives (ES6+)
For shallow comparison:
const shallowEqual = (obj1, obj2) =>
Object.keys(obj1).length === Object.keys(obj2).length &&
Object.keys(obj1).every(key => obj1[key] === obj2[key]);
For JSON-compatible objects:
const jsonEqual = (obj1, obj2) =>
JSON.stringify(obj1) === JSON.stringify(obj2);
Recommended Workflow
- Use
instanceof
for class/prototype checks - Use
Object.keys
/Object.entries
for shallow property inspection - Use Lodash's
_.isEqual
for deep comparison - For custom needs, implement specialized comparators
Pro Tip: When using Lodash, import only needed functions to reduce bundle size:
import isEqual from 'lodash/isEqual';