Understanding Abstract vs. Strict Equality in JavaScript: Beyond the Basics
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:
Abstract Equality Comparison (
==
)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
If
Type(x)
is the same asType(y)
, return the result of the strict equality comparisonx === y
.If
x
isnull
andy
isundefined
, orx
isundefined
andy
isnull
, returntrue
.If
Type(x)
isNumber
andType(y)
isString
, returnx == ToNumber(y)
.If
Type(x)
isString
andType(y)
isNumber
, returnToNumber(x) == y
.If
Type(x)
isBoolean
, return the result of the comparisonToNumber(x) == y
.If
Type(y)
isBoolean
, return the result of the comparisonx == ToNumber(y)
.If
Type(x)
is eitherString
,Number
, orSymbol
andType(y)
isObject
, return the result of the comparisonx == ToPrimitive(y)
.If
Type(x)
isObject
andType(y)
is eitherString
,Number
, orSymbol
, return the result of the comparisonToPrimitive(x) == y
.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
If
Type(x)
is different fromType(y)
, returnfalse
.If
Type(x)
isUndefined
, returntrue
.If
Type(x)
isNull
, returntrue
.If
Type(x)
isNumber
, then:If
x
isNaN
, returnfalse
.If
y
isNaN
, returnfalse
.If
x
is the same number value asy
, returntrue
.If
x
is+0
andy
is-0
, returntrue
.If
x
is-0
andy
is+0
, returntrue
.Return
false
.
If
Type(x)
isString
, then returntrue
ifx
andy
are exactly the same sequence of characters. Otherwise, returnfalse
.If
Type(x)
isBoolean
, then returntrue
ifx
andy
are bothtrue
or bothfalse
. Otherwise, returnfalse
.If
Type(x)
isObject
, then returntrue
ifx
andy
refer to the same object. Otherwise, returnfalse
.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
Falsy Values:
console.log(false == 0); // true console.log(false === 0); // false console.log('' == 0); // true console.log('' === 0); // false
Type Coercion:
console.log(' \t\r\n' == 0); // true (whitespace characters are converted to 0) console.log(' \t\r\n' === 0); // false
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.
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.