Explain, please, why of the three alerts below, only the last one is executed? It seems like in all three cases there is a soft comparison for equality to true

 if (true == "0") alert('Тру равно нулю!'); if ("0" == true) alert('Ноль равен тру'); if ("0") alert('Как бы тоже тру, или как?'); 

https://jsfiddle.net/z1xbshmk/

  • in comparison, "0" is converted to false, in the last line there is no comparison, a non-empty string is converted to true. Here it is written - When comparing with the help “==” - a numerical conversion, and in if - a logical one, that's all. - Jean-Claude

2 answers 2

It is worth referring to the specification.
When calculating EqualityExpression == RelationalExpression , the values ​​of the left and right parts are obtained, and the Abstract Equality Comparison is applied to them.

Comparing x == y, where x and y are values, returns true or false . Such a comparison is made as follows:
If Type (x) is the same as Type (y) , then the result of executing Strict Equality Comparison x === y is returned.
If x is null and y is undefined , return true .
If x is undefined and y is null , return true .
If Type (x) is Number and Type (y) is String , return the result of the expression x == ToNumber (y) .
If Type (x) is String and Type (y) is Number , return the result of the expression ToNumber (x) == y .
If Type (x) is Boolean , return the result of the expression ToNumber (x) == y .
If Type (y) is Boolean , return the result of the expression x == ToNumber (y) .
If Type (x) is one of the following: String , Number , or Symbol and Type (y) is Object , return the value of the expression x == ToPrimitive (y) .
If Type (x) is Object and Type (y) is one of the following: String , Number , or Symbol , return the value of the expression ToPrimitive (x) == y .
Return false .

Consider the first example:

 true == "0" 

This expression corresponds to the branch

If Type (x) is Boolean , return the result of the expression ToNumber (x) == y .

When casting to a number, we get the expression: 1 == "0"
we fall into the branch

If Type (x) is Number and Type (y) is String , return the result of the expression x == ToNumber (y) .

When casting to a number, we get the expression: 1 == 0 and as a result: false .

With the second case, the same happens.

Now consider the third case.

Refer again to the specification :

The ToBoolean function is applied to the expression inside the brackets, which in the case of a string, returns false if the string is empty (the length of the string is 0), and true otherwise.

Since "0" is not empty (the length of string 1), the condition is considered fulfilled.

  • Thank you, great explanation! - tekken
  1. The string is converted to zero, which is interpreted as a lie.
  2. The same thing, just the opposite arguments.
  3. This is not an empty string, it is treated as true .

How does it happen ?

  • Well, actually I came from there. What you describe is a retelling of my question. It's just that in the textbook it is not indicated that in the absence of a comparison operator, toBoolean is implicitly called (well, or I did not read it carefully). But thank you for your attention! - tekken
  • @tekken, the answer seems to be as it is, by the way, the answer from Grundy is much better. I recommend not using == - this is a potential shot in the leg, always use === ; I did not lose anything, but I protected myself from mysterious lags, since the types for comparison are converted quite ambiguously (it would be worth correcting it in new specifications, of course). - user207618