When I studied computer science for five years there was a lot of mathematics. Equality was probably the simplest part. After ten years of working, I’ve done a lot of JavaScript. Equality is not the simplest part… Why?
false == 0 // true ['1', '2', '3'] == '1,2,3' // true undefined == null // true "wtf" == "WTF" // false
First of all, JavaScript has two operators for equality: ==
and ===
. In order to understand equality, we have to understand the difference between these two options. As we know equality from other programming languages and mathematics, ===
behaves the way we are used to.
So, if you’re able to keep ==
away from the JavaScript-codebase you’ll probably save yourself from unnecessary heart disease. Unfortunately, sooner or later we have to make changes in a codebase where ==
is commonly used - then it’s important to understand the consequences of making changes!
x == y
There are a lot of rules to be aware of when using ==
. Let’s take a walkthrough of these rules and try to understand them by some examples.
1 If x
and y
is the same data type the behavior of ==
is the same as ===
1==1 => 1===1 "abc" == "ABC => "abc" === "ABC" [1,2,3] == [1,2,3] => [1,2,3] === [1,2,3]
This is a rule that can make refactoring ==
to ===
a bit easier. If you expect both values to be the same data type - add another equal sign and breathe!
2 Truthy if x
and y
is undefined
and null
null == undefined // true undefined == null // true null === undefined // false
null
and undefined
are special cases and we have to accept that they are equal when using double-quotes. But I’m not sure if I like it...
3 If x
and y
are the data types number and string - try to convert the string into number and perform ==
'2' == 2 => Number('2') == 2 // true '2.5' == 2.5 => Number('2.5') == 2.5 // true '' == 0 => Number('') == 0 // true 'evil' == 666 => Number('evil') == 666 // false BigInt(2) == "2" -> BigInt(2) == BigInt("2") // true
If one value is a string type and the other is numeric, JavaScript compares the numeric value of the string. Remember, converting an empty string to a number results in 0
.
4 If x
or y
is a boolean type - convert it to a number and perform ==
false == 0 => 0 == 0 // true false == '0' => 0 == '0' => 0 == 0 // true true == 1 => 1 == 1 // true false == '' => 0 == '' => 0 == 0 // true
Boolean values converted to a number type results in 0 (false
) or 1 (true
). Be aware of the second line, after converting false
to 0 the comparison is now a numeric and string data type. Fortunately, you have just learned how this works!
5 If x
and y
is respectively an Object and either String, Number, Bigint or Symbol - convert the Object to primitive and perform ==
['1', '2', '3'] == '1,2,3' => ['1', '2', '3'].toString() === '1,2,3' // true [1,2,3] == '1,2,3' => true const me = { toString() { return "lazy"; }, valueOf() { return "1337" } } const you = { toString() { return "lazy"; }, valueOf() { return { key: "1337" } } } me == "lazy" // false me == "1337" // true me == [1,3,3,7] // false you == "lazy" // true you == {key: "1337"} // false me == BigInt(1337) // true me == 1337 // true
Converting the data type object into primitive is usually done by returning the value of valueOf()
-function. If this is not implemented or does not return a primitive value, then it returns the value of toString()
-function.
6 If x
and y
is BigInt and Number then return true
if the mathematical value is the same
123 == BigInt(123) // true 999 == BigInt(123) // false
7 If none of the above applies, return false
!
[1,2,3] == { valueOf() { return "1,2,3" } } // false since both are objects 0 == null // false 0 == NaN // false 0 == undefined // false null == false // false NaN == false // false undefined == false // false
As mentioned above, avoid using ==
in your JavaScript code. Unless all of the rules above fits in your, and your teammates, head - please use ===
!
Relevant resources recommended by the author
Woops. An error has occured, and we are not able to find the link!
Woops. An error has occured, and we are not able to find the link!
Woops. An error has occured, and we are not able to find the link!