When you dive into JavaScript, one of the first things you'll notice is its strict equality operator (===
). At first glance, it seems straightforward, but some cases might leave you scratching your head. Let's explore why 1 === 1
evaluates to true
while {} === {}
evaluates to false
.
The Memory Game: Primitives vs Objects
To understand this behavior, you need to know how JavaScript handles primitives and objects in memory.
Primitives
Primitives include values like numbers, strings, booleans, undefined
, null
, and symbols. When you compare two primitive values using ===
, JavaScript checks if their values are the same. Since both 1
in 1 === 1
refer to the same value, the comparison returns true
.
Objects
Objects, on the other hand, are more complex. They are stored in a special area of memory called the heap. Every time you create an object, it gets a new memory location in the heap. When you use ===
to compare objects, JavaScript checks if the two objects refer to the same memory location. Since {}
and {}
are two different objects created in memory, they don't share the same location, and {} === {}
evaluates to false
.
A Deeper Dive: Memory and the Heap
Here’s a simplified diagram to illustrate:
const obj1 = {}; // Created at memory location A
const obj2 = {}; // Created at memory location B
console.log(obj1 === obj2); // false, because A !== B
const obj3 = obj1; // obj3 points to the same location as obj1
console.log(obj1 === obj3); // true, because both point to A
This difference arises because objects are reference types, meaning comparisons check if the references are identical, not the contents.
Using typeof
to Inspect Values
The typeof
operator in JavaScript can help you understand the type of a value. Here's how it works:
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined);// "undefined"
console.log(typeof null); // "object" (a known bug!)
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof function () {}); // "function"
Surprise: null
and Arrays Are Objects
You might notice something odd: typeof null
returns "object." This is a historical mistake in JavaScript that can't be fixed without breaking the web. Arrays and functions, however, are intentionally objects under the hood.
Functions Are Special Objects
Functions are indeed objects, but they come with a unique property: [[Call]]
. This internal property makes them callable, which is why you can invoke them like this:
function greet() {
console.log("Hello!");
}
greet(); // "Hello!"
Why This Matters
Understanding the distinction between primitives and objects is essential for writing robust JavaScript code. When comparing objects, use deep equality checks if you want to compare their contents. For instance:
const objA = { name: "Alice" };
const objB = { name: "Alice" };
// Shallow equality
console.log(objA === objB); // false
// Deep equality
const isEqual = JSON.stringify(objA) === JSON.stringify(objB);
console.log(isEqual); // true
Conclusion
The key takeaway is that 1 === 1
evaluates to true
because primitives are compared by value, while {} === {}
evaluates to false
because objects are compared by reference. With this knowledge, you’re one step closer to mastering JavaScript's quirks and intricacies!
Top comments (0)