When two operators are compared or matched in JavaScript, the internal evaluation process depends on the type of comparison operator being used. This includes strict equality (===
), loose equality (==
), and relational operators (<
, >
, etc.). JavaScript uses a mix of type conversion, value comparison, and algorithmic steps to determine the result. Let’s dive into the details.
1. Equality Operators
Loose Equality (==
)
The ==
operator compares two values for equality after performing type coercion (it is the process of automatically or explicitly converting a value from one data type to another, such as from a string to a number or vice versa in JavaScript) if they are of different types. JavaScript follows these steps internally:
Same Type: If the values are of the same type, compare them directly:
1 == 1
→true
(both are numbers).'hello' == 'hello'
→true
(both are strings).
Different Types:
String and Number: Convert the string to a number, then compare.
'5' == 5 → Number('5') == 5 → 5 == 5 → true // Again 5 == '5' → 5 == Number('5') → 5 == 5 → true
Boolean and Non-Boolean: Convert the boolean to
1
(fortrue
) or0
(forfalse
), then compare.true == 1 → 1 == 1 → true false == 0 → 0 == 0 → true
null
andundefined
:null == undefined → true
==
(loose equality) compares values without considering their types, sonull
andundefined
are considered equal in this case. This is an exception in JavaScript where they are loosely equal to each other.
null == undefined → true
null == 0 → false
null
is not equal to0
because==
performs type coercion. JavaScript does not convertnull
to0
when compared with==
.
null >= 0
andnull <= 0
null >= 0
→ true andnull <= 0
→ true because whennull
is coerced to a number, it becomes0
. So,null
is treated as0
and thus both comparisons evaluate to true.
null > 0
andnull < 0
null > 0
→ false andnull < 0
→ false becausenull
coerces to0
, and0
is neither greater than nor less than0
.
// null is not equal to 0
console.log(null == 0); // false
// null is coerced to 0 in numeric comparison
console.log(null >= 0); // true
console.log(null <= 0); // true
console.log(null > 0); // false
console.log(null < 0); // false
undefined == 0 → false
undefined == 0
is false becauseundefined
cannot be converted to a numeric value when compared using==
. Therefore, they are not equal.
undefined >= 0
,undefined <= 0
,undefined > 0
,undefined < 0
- Comparisons involving
undefined
(likeundefined >= 0
,undefined <= 0
, etc.) will result infalse
in JavaScript becauseundefined
cannot be coerced into a number and return NaN and thus cannot be compared to numeric values. So all these comparisons evaluate tofalse
.
- Comparisons involving
// undefined is not equal to 0
console.log(undefined == 0); // false
// undefined cannot be compared with numbers
console.log(undefined >= 0); // false
console.log(undefined <= 0); // false
console.log(undefined > 0); // false
console.log(undefined < 0); // false
Object and Primitive: Convert the object to its primitive equivalent using
valueOf()
ortoString()
and then compare.[1] == 1 → '1' == 1 → Number('1') == 1 → 1 == 1 → true
Another Example:
[1, 'Hridoy', 45, true] == '4,5' // '1,Hridoy,45,true' == '4,5' → false
Explanation:
The array
[1, 'Hridoy', 45, true]
is converted to a string by calling itstoString()
method, which results in the string'1,Hridoy,45,true'
.The comparison is then between the string
'1,Hridoy,45,true'
and the string'4,5'
.Since these two strings are not equal, the result of the comparison is
false
.
Notes:
No type conversion happens if both values are
null
orundefined
; they are considered equal only to each other.NaN
is not equal to any value, including itself.
Strict Equality (===
)
The ===
operator checks for equality without type coercion. Both the value and the type must be identical for the comparison to return true
.
Same Type: If the values are of the same type, compare them directly:
5 === 5
→true
(same type and value).'abc' === 'abc'
→true
(same type and value).
Different Types: If the types are different, the result is always
false
:'5' === 5 → false true === 1 → false
Special Cases:
NaN === NaN
→false
(NaN is not equal to itself).0 === -0
→true
(both are considered equal in JavaScript).
2. Relational Operators (<
, >
, <=
, >=
)
Relational operators convert the operands to primitives (if needed) and compare their values using a numeric or lexicographic comparison, depending on the type.
Steps for Relational Comparisons:
Primitive Conversion:
If the operands are objects, JavaScript calls their
valueOf()
ortoString()
methods to get primitive values.Example:
let obj = { valueOf: () => 5 }; console.log(obj > 3); // true
String vs. String:
- Strings are compared lexicographically (character by character based on Unicode values).
'apple' < 'banana' → true (based on dictionary order)
'5' > '12' → true (because '5' comes after '1' lexicographically)
String and Number:
- Convert the string to a number and perform a numeric comparison.
'5' > 2 → Number('5') > 2 → 5 > 2 → true
Non-Primitives:
- Convert objects to primitives, then compare.
[5] < 10 → Number([5]) < 10 → 5 < 10 → true
Edge Cases:
- Comparing
null
orundefined
to a number convertsnull
to0
andundefined
toNaN
.
- Comparing
null < 1 → 0 < 1 → true
undefined < 1 → NaN < 1 → false
3. Logical Operators (&&
, ||
, !
)
Logical operators (&&
, ||
, !
) return one of the operands rather than a boolean in some cases. They follow short-circuit evaluation.
Steps:
Logical AND (
&&
):If the first operand is falsy, return it.
Otherwise, return the second operand.
0 && 'hello' → 0
true && 'world' → 'world'
Logical OR (
||
):If the first operand is truthy, return it.
Otherwise, return the second operand.
null || 'hello' → 'hello'
'world' || 0 → 'world'
Logical NOT (
!
):- Converts the operand to a boolean and negates it.
!true → false
!0 → true
4. Primitive Conversion Details
ToPrimitive Conversion:
JavaScript attempts to convert objects to primitives during comparison:
Calls
valueOf()
first.If
valueOf()
returns a non-primitive, callstoString()
.Throws an error if neither produces a primitive.
let obj = {
valueOf: () => 5,
toString: () => '10'
};
console.log(obj > 3); // true (uses valueOf())
console.log(obj + ''); // '5' (uses valueOf())
console.log(obj > 3);
The expression
obj > 3
involves a comparison operation. When comparing objects with numbers, JavaScript tries to convert the object to a primitive (number) for the comparison.obj.valueOf()
returns5
, so the expression becomes5 > 3
, which istrue
.
Result:
true
.
console.log(obj + '');
In this case, JavaScript is concatenating the object with an empty string (
''
).obj.toString()
returns'10'
, so the expression becomes'10' + ''
, which results in'10'
.
Result:
'10'
.