Understanding Abstract vs. Strict Equality in JavaScript: Beyond the Basics

Shivam KumarShivam Kumar
4 min read

In the realm of JavaScript development, equality comparisons often lead to confusion and misconceptions, especially when it comes to Abstract Equality (==) and Strict Equality (===). Many developers, especially those new to JavaScript, might believe that the difference lies solely in type checking. However, this is a surface-level understanding. In reality, both Abstract and Strict Equality perform type checking, but Abstract Equality includes an additional step of type coercion if the types do not match.

In this blog, we will unravel the nuances of these two comparison operators, explaining their algorithms, types, and how JavaScript internally processes them, as described in the ECMAScript documentation.

Comparison Operators in JavaScript

JavaScript provides two primary types of equality comparison operators:

  1. Abstract Equality Comparison (==)

  2. Strict Equality Comparison (===)

Both operators are used to compare two values but have different approaches and rules.

Misconceptions

On the Internet, many developers state that Abstract Equality doesn’t check for data types while Strict Equality does. This is often said by those who haven't deeply explored JavaScript or gained significant experience with it. The truth is more nuanced.

Abstract Equality Comparison (==)

Abstract Equality Comparison checks the equality of two values and performs type coercion if necessary. This means it converts the values to a common type before making the comparison.

Steps Involved in Abstract Equality Algorithm

  1. If Type(x) is the same as Type(y), return the result of the strict equality comparison x === y.

  2. If x is null and y is undefined, or x is undefined and y is null, return true.

  3. If Type(x) is Number and Type(y) is String, return x == ToNumber(y).

  4. If Type(x) is String and Type(y) is Number, return ToNumber(x) == y.

  5. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.

  6. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

  7. If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).

  8. If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.

  9. Return false if none of the above conditions are met.

Note: These steps are not invented by developers but are part of the official ECMAScript documentation.

Example of Abstract Equality

console.log(2 == '2'); // true
console.log(null == undefined); // true
console.log(true == 1); // true
console.log([] == ''); // true
console.log('0xa' == 10); // true

Strict Equality Comparison (===)

Strict Equality Comparison checks the equality of two values without performing any type coercion. This means that both the type and the value must be the same for the comparison to return true.

Steps Involved in Strict Equality Algorithm

  1. If Type(x) is different from Type(y), return false.

  2. If Type(x) is Undefined, return true.

  3. If Type(x) is Null, return true.

  4. If Type(x) is Number, then:

    • If x is NaN, return false.

    • If y is NaN, return false.

    • If x is the same number value as y, return true.

    • If x is +0 and y is -0, return true.

    • If x is -0 and y is +0, return true.

    • Return false.

  5. If Type(x) is String, then return true if x and y are exactly the same sequence of characters. Otherwise, return false.

  6. If Type(x) is Boolean, then return true if x and y are both true or both false. Otherwise, return false.

  7. If Type(x) is Object, then return true if x and y refer to the same object. Otherwise, return false.

  8. Return false if none of the above conditions are met.

Note: These steps are taken directly from the official ECMAScript documentation.

Example of Strict Equality

console.log(2 === '2'); // false
console.log(null === undefined); // false
console.log(true === 1); // false
console.log([] === ''); // false
console.log('0xa' === 10); // false

Pitfalls of Equality Comparisons

Understanding the subtleties of equality comparisons can help you avoid common pitfalls that can lead to bugs and unexpected behavior.

Pitfall Examples

  1. Falsy Values:

     console.log(false == 0); // true
     console.log(false === 0); // false
     console.log('' == 0); // true
     console.log('' === 0); // false
    
  2. Type Coercion:

     console.log(' \t\r\n' == 0); // true (whitespace characters are converted to 0)
     console.log(' \t\r\n' === 0); // false
    
  3. Objects and Primitives:

     console.log([1,2] == '1,2'); // true (array is converted to string)
     console.log([1,2] === '1,2'); // false
     console.log({} == '[object Object]'); // false
     console.log({} === '[object Object]'); // false
    

Summary

Understanding the difference between Abstract Equality (==) and Strict Equality (===) is crucial for avoiding common pitfalls in JavaScript. Both operators perform type checking, but Abstract Equality allows type coercion while Strict Equality does not. By following the detailed steps of each algorithm, developers can make informed decisions about which operator to use in different scenarios.

Further Reading

By diving deeper into the ECMAScript documentation and understanding these algorithms, you'll gain a more robust comprehension of how JavaScript handles equality and comparison, moving beyond common misconceptions and towards expert-level knowledge.

1
Subscribe to my newsletter

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

Written by

Shivam Kumar
Shivam Kumar

As a recent Computer Science graduate with a passion for backend development, I’m skilled in JavaScript, Node.js, React, Express, MongoDB, and MySQL. I have experience with Docker, Kubernetes, RabbitMQ, and gRPC, and am familiar with RESTful APIs and microservices. Dedicated and analytical, I’m improving my communication skills and enjoy watching anime in my free time. I’m excited to join a team focused on innovation and growth.