As the title states, why does:
> !!1=="1"
equal
True
and
> !!2=="2"
equal:
False
Likewise, why does > "1"==true
equal true
and > "2"==true
equal false
I'm baffled. Are these just bugs in JS or what's going on here?
Each object, each {} is distinct. Same applies to arrays, too. Show activity on this post. 2) it does not make any difference whether you use == or === for comparing objects, because comparing them always returns false.
The comparison operator ==, when used with objects, checks whether two objects are the same one. Since there are two {} in the statement {} == {}, two new objects are created separately, and then they are compared. Since they are not the same object, the result is false.
1 is considered to be true because it is non-zero. The fourth expression assigns a value of 0 to i. 0 is considered to be false.
In JavaScript “0” is equal to false because “0” is of type string but when it tested for equality the automatic type conversion of JavaScript comes into effect and converts the “0” to its numeric value which is 0 and as we know 0 represents false value. So, “0” equals to false.
As per the Operator precedence rules, logical !
has higher priority over ==
. So, in both the cases, !!
is evaluated first.
Note: Truthiness of various objects have been explained in this answer of mine.
!!1 == "1"
!1
will be evaluated to false
, since 1
is considered Truthy. Negating again we get true
. So the expression becomes
true == "1"
Now, the coercion rules kick in as you have used ==
operator, which evaluates as per the The Abstract Equality Comparison Algorithm defined in ECMAScript 5.1 Specification,
6. If
Type(x)
isBoolean
, return the result of the comparisonToNumber(x) == y
.
So, true
will be converted to a number, which is 1 as per ToNumber
algorithm for Boolean values. Now the expression becomes
1 == "1"
Now,
4. If
Type(x)
isNumber
andType(y)
isString
, return the result of the comparisonx == ToNumber(y)
.
So, "1"
will be converted to a number and that will give 1, as per the ToNumber
algorithm. That is why it shows true
in the first case.
The same rules are applied here.
!!2 == "2"
becomes
true == "2"
then
1 == "2"
which becomes
1 == 2
which is not true
, that is why the second case prints false
.
tldr; this is due to the [ToNumber] conversions in the ==
operator algorithm.
The first step is to simplify the expression. Since !!x=="x"
is parsed like (!!x)=="x"
and !!a_truthy_expression -> true
, the actual relevant expression for the equality is
!!1=="2" -> true=="1" -> Boolean==String !!2=="2" -> true=="2" -> Boolean==String
So then looking at the rules for 11.9.3 The Abstract Equality Comparison Algorithm and following along with the application yields
Rule 6 - If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
which results in Number==String
or 1=="1" and 1=="2", respectively1. Then the rule
Rule 7 - If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
is applied which results in Number==Number
or 1==1 and 1==2, respectively1; the latter is clearly false.
Rule 1 - If Type(x) is the same as Type(y), then [by c.iii.] If x is the same Number value as y, return true [else return false].
(The same algorithm explains the String==Boolean
case when the complementing rules are applied.)
1To see the [ToNumber] rule applied, consider:
+false -> 0 +true -> 1 +"1" -> 1 +"2" -> 2
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