Equality Comparisons in JavaScript

SaqibSaqib
4 min read

In JavaScript, there are several kinds of equality. If you’ve been writing JavaScript for a while, you’re probably familiar with at least two of them:

  • Strict Equality: a === b (triple equals).

  • Loose Equality: a == b (double equals).

  • Same Value Equality: Object.is(a, b).

Strict Equality ===

In JavaScript, Strict equality (===) is a way of comparing two values for equality without converting either. If the values being compared are different, they are considered unequal. However, if they are of the same type and are not numbers, they are considered equal if they have the same value.

// Same Type, Same Value:
console.log("Hello" === "Hello"); // true
console.log(42 === 42); // true

// Different Types:
console.log("42" === 42); // false

However, there are two rare cases where the behavior of === is different.

For numbers, there's a bit of a special case. They are considered equal if they have the same value and are not NaN (Not-a-Number). Additionally, +0 and -0 are considered equal.

  1. NaN === NaN is false, although they are the same value.

  2. -0 === 0 and 0 === -0 are true, although they are different values.

console.log(0 === -0); // true
console.log(NaN === NaN); // false

Loose Equality ==

In JavaScript, loose equality (==) comparison involves a process known as "type coercion". This process converts the operands to a common type before making the comparison. The algorithm for loose equality can be summarized in the following steps:

  1. If the operands have the same type, they are compared as follows:

    • Object: return true only if both operands reference the same object.

    • String: return true only if both operands have the same characters in the same order.

    • Number: return true only if both operands have the same value. +0 and -0 are treated as the same value. If either operand is NaN, return false; so NaN is never equal to NaN.

    • Boolean: return true only if operands are both true or both false.

  2. If one of the operands is null or undefined, the other must also be null or undefined to return true. Otherwise, return false.

  3. If one of the operands is an object and the other is a primitive, convert the object to a primitive.

// Object equality
const obj1 = { key: "value" };
const obj2 = { key: "value" };
console.log(obj1 == obj2); // false, as they reference different objects

// String equality
console.log("hello" == "hello"); // true, same characters in the same order
console.log("hello" == "world"); // false, different characters

// Number equality
console.log(5 == 5); // true, same value
console.log(+0 == -0); // true, +0 and -0 are treated as the same value
console.log(NaN == NaN); // false, NaN is never equal to NaN

// Boolean equality
console.log(true == true); // true, both operands are true
console.log(false == false); // true, both operands are false
console.log(true == false); // false, one is true and the other is false

// Null and Undefined equality
console.log(null == null); // true, both operands are null
console.log(undefined == undefined); // true, both operands are undefined
console.log(null == undefined); // true, special case for null and undefined
console.log(null == "hello"); // false, different types

Same Value Equality Object.is(a, b)

The Object.is() method in JavaScript provides a straightforward and precise way to compare values for equality. It's designed to handle edge cases more consistently than the loose equality (==) and strict equality (===) operators.

// Basic equality
console.log(Object.is(5, 5)); // true
console.log(Object.is("hello", "hello")); // true

// NaN equality
console.log(Object.is(NaN, NaN)); // true

// +0 and -0 equality
console.log(Object.is(+0, -0)); // false

// Object references
const obj1 = { key: "value" };
const obj2 = { key: "value" };
console.log(Object.is(obj1, obj1)); // true, same object reference
console.log(Object.is(obj1, obj2)); // false, different object references

// Special case: null and undefined
console.log(Object.is(null, undefined)); // false
💡
Despite Object the method name, Object.is is not specific to objects. It can compare any two values, whether they are objects or not!

Wrap up:

If you found this helpful, a like would mean a lot! Share it with your friends in the coding world so we can all learn together.

Feel free to connect with me on Twitter or LinkedIn, and let's continue the conversation.

Thanks for reading, and happy coding! 🚀🌟

0
Subscribe to my newsletter

Read articles from Saqib directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Saqib
Saqib

I'm a software engineer committed to lifelong learning and constantly improving my skills.