We all know javascript does funky conversions when testing for equality, but what exactly happens under the hood?
> [0] == 0
true
> 0 == [[0]]
true
> [0] == [[0]]
false
Yes, it was naive of me to expect transitivity from == operator.
[0] == 0
and 0 == [[0]]
compares a primitive value with an object and thus type conversion will be performed. In both cases [0]
and [[0]]
will eventually be converted to the primitive value 0
.
This is defined in steps 8 (and 9) of the The Abstract Equality Comparison Algorithm:
- If Type(x) is either String or Number and Type(y) is Object,
return the result of the comparison x == ToPrimitive(y).
However, [0] === [[0]]
compares two objects and two different objects are never equal to each other:
1f. Return true if x and y refer to the same object. Otherwise, return false.
Here is a slightly simper example that demonstrates that loose comparison is not transitive:
" " == 0 // true
"\n" == 0 // true
" " == "\n" // false
The first two comparisons perform type conversion (string to number), the last one does not and the values of both strings are different.
Your first 2 examples implicitly converts the arrays to strings, then compares those to the 0
:
var a = [0].toString(); // "0"
var b = a == 0 // "0" == 0; // true
The last example doesn't cast the arrays, it just compares the arrays' identities.
These don't match, obviously, so false
is returned.
The extra layer of depth you have in some of those arrays doesn't make a difference, in your examples:
[0] == [0] // false, they're not the same array.
0 == [[[[0]]]] // true, [[[[0]]]].toString() === "0", "0" == 0
As @JanDvorak mentioned in a comment on @KooiInc's answer, behind the scenes, JS doesn't use toString
for this conversion. However, in concept this is what's happening.
The behaviour is as per JavaScript The Abstract Equality Comparison Algorithm
Matches Case 9 of algo: Type(x) is Object and Type(y) is either String or Number
result: ToPrimitive(x) == y. i.e '0' == 0, hence true
Matches Case 8 of algo: If Type(x) is either String or Number and Type(y) is Object, result: x == ToPrimitive(y). i.e 0 == '0', hence true
Matches Case 1 of algo: Type(x) is the same as Type(y), if type is 'object' Return true if x and y refer to the same object. Otherwise, return false. i.e reference will be matched, hence false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With