Why does !!1==“1” equal true and !!2==“2” equal false?

后端 未结 5 1438
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-07 15:47

As the title states, why does:

> !!1==\"1\"

equal

True

and

> !!2==\"2\"


        
相关标签:
5条回答
  • 2020-12-07 16:02

    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
    
    0 讨论(0)
  • 2020-12-07 16:07

    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.

    0 讨论(0)
  • 2020-12-07 16:08

    !!1 is equal to true, and "1" is equal to true ("0" is false, so is every other string). So !!1 == "1" evaluates to true == true, which of course returns true.

    !!2 is also equal to true. As I mentioned earlier, "2" is not "1", so it's false. Therefore, we have true == false, which of course returns false.

    If you want to see if 2 (a number) is equal to "2" (a string representation of a number), then all you have to do is 2 == "2", which evaluates to 2 == 2, which is true. The difference is that we're not comparing a boolean against a boolean. We're comparing a number against a number.

    Basically, putting !! in front of a number converts to a boolean, which forces JavaScript to cast your string to a boolean instead of a number.

    0 讨论(0)
  • 2020-12-07 16:09

    Its a precedence operator problem.

    The ! operator is an unary operator. That means the left side must be an expression or a boolean evaluable section. See Javascript MDN.

    !!1==1 is not necessary !!(1==1)
    !!2==2 is not necessary !!(2==2)
    

    I think that these expressions should be consistent if the equal operator has more precedence than ! operator. But if we consider the opposite, evaluating first negations we have:

    !!1 == 1
    !1 -> false
    !!1 -> true
    !!1 == 1 
    

    And with the two

    !!2==2
    !2 -> false
    !!2 -> true
    (!!2) == 2 -> false
    

    That is because the ! operator has precedence over == operator

    See Mozilla Operator Preference

    0 讨论(0)
  • 2020-12-07 16:24

    Because "1" may be considered as "true" when you do equality check, not identity, but "2" - can't.

    0 讨论(0)
提交回复
热议问题