Using == to compare objects/arrays

Loading

Using == to Compare Objects/Arrays in JavaScript: A Comprehensive Guide

๐Ÿ“Œ Introduction

JavaScript provides two main comparison operators:

  1. == (Loose Equality or Abstract Equality): Converts the values to the same type before comparing.
  2. === (Strict Equality): Compares both value and type without conversion.

When dealing with objects and arrays, many developers mistakenly use == (or even ===) expecting correct results. However, these operators do not compare the actual contents of objects or arrays but rather their references in memory.

In this guide, we will:

  • Understand how JavaScript compares objects and arrays.
  • See common pitfalls when using == for comparison.
  • Explore correct methods to compare objects and arrays.

1๏ธโƒฃ Primitive vs. Reference Types in JavaScript

Before diving into comparisons, we need to understand how JavaScript stores data.

๐Ÿ”น Primitive Data Types (Compared by Value)

Primitive types include:

  • string, number, boolean, null, undefined, bigint, symbol

When comparing two primitive values, JavaScript compares their actual values.

console.log(5 == 5);     // true
console.log("hello" === "hello"); // true
console.log(null == undefined);   // true
console.log(0 == false);  // true (Type coercion occurs)

๐Ÿ”น Reference Types (Compared by Memory Address)

Objects, arrays, and functions are reference types. They are stored as memory addresses (references), not actual values.

let obj1 = { a: 1 };
let obj2 = { a: 1 };

console.log(obj1 == obj2);   // false
console.log(obj1 === obj2);  // false

Even though both objects have the same properties, they are stored at different memory locations, so the comparison fails.


2๏ธโƒฃ Why == Fails with Objects and Arrays

Unlike primitive values, == (or even ===) does not check the internal contents of objects or arraysโ€”it only checks if they reference the same memory location.

๐Ÿ”ธ Example 1: Comparing Two Different Objects

let objA = { name: "Alice" };
let objB = { name: "Alice" };

console.log(objA == objB);   // false
console.log(objA === objB);  // false

๐Ÿ”น Why?

  • objA and objB hold different memory addresses, even though they have identical properties.

๐Ÿ”ธ Example 2: Comparing Two Arrays

let arr1 = [1, 2, 3];
let arr2 = [1, 2, 3];

console.log(arr1 == arr2);   // false
console.log(arr1 === arr2);  // false

๐Ÿ”น Why?

  • Arrays are objects, and each array is stored at a different memory location.

๐Ÿ”ธ Example 3: Comparing Two Identical Object Variables

let obj1 = { key: "value" };
let obj2 = obj1;  // obj2 now references the same object as obj1

console.log(obj1 == obj2);   // true
console.log(obj1 === obj2);  // true

๐Ÿ”น Why?

  • Both obj1 and obj2 point to the same memory location, so they are considered equal.

๐Ÿ”ธ Example 4: Comparing null and undefined

console.log(null == undefined);  // true
console.log(null === undefined); // false

๐Ÿ”น Why?

  • == considers null and undefined as loosely equal due to type coercion.
  • === checks both type and value, so it returns false.

3๏ธโƒฃ Correct Ways to Compare Objects and Arrays

Since == and === do not compare object content, we need alternative approaches.

โœ… Method 1: Using JSON.stringify() (For Simple Objects)

The easiest way to compare objects is by converting them into JSON strings.

let obj1 = { name: "Alice", age: 25 };
let obj2 = { name: "Alice", age: 25 };

console.log(JSON.stringify(obj1) === JSON.stringify(obj2));  // true

๐Ÿ”น Limitations:

  • The property order matters.
  • Cannot compare functions or circular structures.

โœ… Method 2: Using a Custom Deep Comparison Function

For complex objects, use recursion to compare values.

function deepEqual(obj1, obj2) {
    if (obj1 === obj2) return true; // Same memory reference

    if (typeof obj1 !== "object" || typeof obj2 !== "object" || obj1 === null || obj2 === null)
        return false;

    let keys1 = Object.keys(obj1);
    let keys2 = Object.keys(obj2);

    if (keys1.length !== keys2.length) return false;

    for (let key of keys1) {
        if (!deepEqual(obj1[key], obj2[key])) return false;
    }

    return true;
}

let a = { x: 1, y: { z: 2 } };
let b = { x: 1, y: { z: 2 } };

console.log(deepEqual(a, b));  // true

๐Ÿ”น Why use this?

  • Works for nested objects.
  • Ignores memory reference and checks actual values.

โœ… Method 3: Comparing Arrays Using .every()

function arraysEqual(arr1, arr2) {
    if (arr1.length !== arr2.length) return false;
    return arr1.every((value, index) => value === arr2[index]);
}

let arrA = [1, 2, 3];
let arrB = [1, 2, 3];

console.log(arraysEqual(arrA, arrB));  // true

๐Ÿ”น Why use this?

  • Ensures arrays contain the same elements in the same order.

4๏ธโƒฃ Common Mistakes to Avoid

โŒ Mistake 1: Expecting == to Work for Objects

console.log({} == {});   // false
console.log([] == []);   // false

๐Ÿ”น Fix: Use JSON.stringify() or a deep comparison function.


โŒ Mistake 2: Not Handling Nested Objects

let obj1 = { a: { b: 2 } };
let obj2 = { a: { b: 2 } };

console.log(JSON.stringify(obj1) === JSON.stringify(obj2));  // true (works in this case)
console.log(obj1 === obj2);  // false

๐Ÿ”น Fix: Use a deep comparison function.


โŒ Mistake 3: Expecting == to Compare Object Contents

let objA = { key: "value" };
let objB = { key: "value" };

console.log(objA == objB); // false

๐Ÿ”น Fix: Always compare properties manually or use a utility function.


๐ŸŽฏ Conclusion

  • == and === do not compare object contentsโ€”they only check memory references.
  • Use JSON.stringify() for simple objects and deepEqual() for nested objects.
  • When comparing arrays, use .every() or deep comparison.
  • Be cautious with null and undefined in loose equality (==).

Would you like a ready-made utility function for deep comparisons?

Leave a Reply

Your email address will not be published. Required fields are marked *