Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does !!1=="1" equal true and !!2=="2" equal false?

Tags:

javascript

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?

like image 299
Michael Rader Avatar asked May 16 '14 05:05

Michael Rader


People also ask

Why is {} == {} false?

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.

Why == is 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.

Does 1 equal True or 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.

What is the output of 0 == false and 0 === false Why?

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.


2 Answers

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.

First Case

!!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) is Boolean, return the result of the comparison ToNumber(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) is Number and Type(y) is String, return the result of the comparison x == 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.

Second 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.

like image 194
thefourtheye Avatar answered Oct 17 '22 16:10

thefourtheye


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 
like image 26
user2864740 Avatar answered Oct 17 '22 14:10

user2864740