Why are both the values โ€‹โ€‹of if ('0' == false), and if ('0') evaluates to true in Javascript?

So, I know that the if in Javascript passes the result of its condition to a logical one and then executes it, like the following

 if(true) { // run this } if(false) { // do not run this } 

And it works. But if I do this:

 if('0' == false) { // We get here, so '0' is a falsy value } 

Then I would expect this

 if('0') { // We don't get here, because '0' is falsy value } 

But instead I get

 if('0') { // We *DO* get here, even though '0' is falsy value } 

So what is going on? Apparently, if does not check if its condition is true or false, but does it perform some other conversion?

+4
source share
4 answers

This is just one of those "gotchas" with == rules , which are quite complex.

A comparison of x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

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

(5) If Type (x) is String and Type (y) is Number, returns the result of the comparison ToNumber (x) == y.

(6) If Type (x) is logical, return the result of the comparison ToNumber (x) == y.

(7) If type (y) is Boolean, return the result of the comparison x == ToNumber (y).

In this case, this means that '0' == false first forced to execute '0' == 0 (by rule No. 7), and then on the second pass it is forced to 0 == 0 (by rule No. 5), which leads to to true.

This particular case is somewhat more complicated due to false ~> 0 instead of '0' ~> true (as you would expect). However, '0' itself is the value of true-y, and behavior can be explained using the rules above. In order to have strict plausible equality in the test (which differs from strict equality) without implicit conversions during equality, consider:

 !!'0' == !!false 

(For all values !falsey -> true and !truthy -> false .)

+7
source

It:

 if('0') { // We *DO* get here, even though '0' is falsy value } 

checks if a string is empty or empty and not null or not. Any non-empty string is true.

When you do this:

 if('0' == false) { // We get here, so '0' is a falsy value } 

you are requesting a JS engine for explicit type conversion to try to match the type of the two operands. This is different from just asking if a single operand is true on its own.

In general, you will find that you get fewer unexpected results if you almost always use === and !== and only allow for type coercion, when you know exactly what will happen in all cases, or because you fully understand the very complex coercion rules or because you know what types will be present, and you understand these specific cases.

+3
source

if ('0' == false) :

Javascript is doing something called type coercion .

Following the rules of this link, we come to rule 7:

If type (y) is boolean, return the result of the comparison x == ToNumber (y)

Calling ToNumber (false) gives us the number 0. The result now starts to make sense, but we still havenโ€™t quite done it, because we still have a string and a number. The process starts again, and this time we come to rule 5:

If Type (x) is String and Type (y) is Number, return the result of the comparison ToNumber (x) == y: "2" == 2

This time, the left side of '0' is converted to a number: 0. Now, finally, we can compare two numbers, and since 0 is 0, the result will be true. However, it is important to note that this does not mean anything about the true / false nature of the string '0' , because it was forced before it was compared.

if('0')

In this case, there is no comparison; you only want to know if a single value is true or false. Type type applications are not used because strings can be evaluated as crazy or fake. Using the rules from the same link as before, we find the following information:

In JavaScript, not just JavaScript, we have what are called false values. This is respectively: 0, null, undefined, false, ", NaN. Please note that the empty string is empty, because otherwise than the php example," 0 "will be considered truish

The quote is especially useful because it specifically calls the string "0", but that would not be necessary. This is enough to know that an empty string is false, and any other string is true, because the contents of the string are not evaluated and no enforcement is performed. 0 can be a false value, but because we evaluate the string, and not force it to a number, and '0' has some value, it still remains true.

+3
source

The Javascript == operator does type conversion and is basically useless. Just avoid it.

For instance:

  • [] is truty, but [] == false true
  • 1 == "1" , [1] == "1" , [[1]] == "1" everything is true
  • [1] == [[1]] however false

The rules are VERY weird. For example, in the first case, [] converted to "" , which is converted to a number, and the value is 0 . false also converted to the number 0 . Therefore, in the end, they compare equals.

Note that although converting from an empty string to a number gives 0 , the result of parseInt("") is NaN .

PS: The most interesting thing is when you find that [30,20,10,3,2,1].sort() returns [1,10,2,20,3,30] (yes ... numbers, yes in lexicographical order). No I am not joking.

+1
source

Source: https://habr.com/ru/post/1479824/


All Articles