
Object Equality in JavaScript: {} isn't Equal to {}

I admit, this is one of my go‑to interview questions when looking to hire new front‑end developers into one of my teams (something that I've been doing a lot of recently). The question is simple. Given the code below, can you explain why a == b will return false?
let a = {};let b = {};On the surface of this, it does seem like both a and b should be equal. I tend to find that it is around 50‑50 whether an interviewer understands the reason behind why these two empty objects aren't equal. It also helpfully tends to identify those candidates whose experience lies more in relying on helpers and frameworks rather than understanding the more fundamental aspects of JavaScript and data types.
Understanding Object Identity
The answer to this question lies in how JavaScript handles object comparison. When comparing objects, JavaScript doesn't look at their contents or structure (as it might do with an equality operator on a simple number, boolean, or string variable). Instead, it looks at the object identities ‑ it checks if the objects being compared are exactly the same instance.
In our example, a and b are different objects, each with their own unique references within memory. Even though they have the same structure and content (i.e., empty), they are considered distinct entities within the JavaScript engine. This is a fairly fundamental concept which underpins a lot of JavaScript's behaviour when it comes to objects and their comparison.
Deep Comparison for Objects
If you are ever asked this question in an interview and really want to earn a few extra points, then being able to explain how you would compare two objects (and their contents) would certainly achieve that. JavaScript doesn't offer a built‑in operator for this, but that doesn't mean that it's particularly difficult or a dead end.
You can perform a deep comparison by writing a function that iteratively checks each property and value within the objects or by using utilities provided by libraries like Lodash, which offer methods specifically designed for this purpose.
In JavaScript
If you were to write a utility function to deeply compare two objects, it might look something like this:
const deepEqual = (obj1: any, obj2: any): boolean => { if (obj1 === obj2) { return true; } if ( typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null ) { return false; } const keys1: string[] = Object.keys(obj1); const keys2: string[] = Object.keys(obj2); if (keys1.length !== keys2.length) { return false; } for (let key of keys1) { if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) { return false; } } return true;};const obj1 = { a: 1, b: { c: 1 } };const obj2 = { a: 1, b: { c: 1 } };console.log(deepEqual(obj1, obj2)); //=> trueconst obj3 = { a: 1, b: { c: 2 } };console.log(deepEqual(obj1, obj3)); //=> falseWhat this does is firstly check if both parameters are objects. If they are, we then compare their keys and values. Where it comes across a property that is itself an object, it calls itself recursively, comparing all the way down to the deepest level.
Using Lodash
Alternatively, if you prefer using a library (or if you already have Lodash as a dependency in your project), then the isEqual method will already do this for you:
import isEqual from 'lodash/isEqual';const obj1 = { a: 1, b: { c: 1 } };const obj2 = { a: 1, b: { c: 1 } };console.log(isEqual(obj1, obj2)); //=> trueWrapping up
Although comparing {} with {} and getting false might feel counterintuitive, this is an area that unveils a candidate's understanding of JavaScript's approach to object identity and comparison. Although only a tiny piece of what makes a good developer, this is a concept that is really important when it comes to writing efficient and optimised code. In the realm of objects in JavaScript, identity precedes equality.
Categories:
Related Articles

Pure Functions in JavaScript. 
Check If Three Values are Equal in JavaScript. Check If Three Values are Equal in JavaScript

Break Out of CSS Nesting with Sass. Break Out of CSS Nesting with Sass

Resolving mini‑css‑extract‑plugin Warnings in Gatsby. Resolving
mini‑css‑extract‑pluginWarnings in Gatsby
Understanding Signals in Angular: The Future of Reactivity. Understanding Signals in Angular: The Future of Reactivity

Using data‑* Attributes and dataset in JavaScript. Using
data‑*Attributes anddatasetin JavaScript
The Palindrome Number Problem: Strings vs. Maths in JavaScript. The Palindrome Number Problem: Strings vs. Maths in JavaScript

UseReducer in React. useReducerin React
How Much Do Software Engineers Make in the UK? How Much Do Software Engineers Make in the UK?

Object.keys(), Object.values(), and Object.entries() Explained. Object.keys(),Object.values(), andObject.entries()Explained
Vue's provide/inject API: When and How to Use It. Vue's
provide/injectAPI: When and How to Use It
Disabling Text Selection Highlighting with CSS. Disabling Text Selection Highlighting with CSS