In JavaScript, Why Is "0" Equal to False, But When Tested by 'If' It Is Not False by Itself

In JavaScript, why is 0 equal to false, but when tested by 'if' it is not false by itself?

The reason is because when you explicitly do "0" == false, both sides are being converted to numbers, and then the comparison is performed.

When you do: if ("0") console.log("ha"), the string value is being tested. Any non-empty string is true, while an empty string is false.

Equal (==)

If the two operands are not of the same type, JavaScript converts the operands then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the other operand is converted to a string if possible. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.

(From Comparison Operators in Mozilla Developer Network)

why do both if('0'==false) and if('0') evaluate to true in Javascript?

This is just one of those "gotchas" with the == rules which are rather complex.

The comparison 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,
return the result of the comparison ToNumber(x) == y.

(6) If Type(x) is Boolean, 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 that means that '0' == false is first coerced do '0' == 0 (by rule #7) and then on the second pass through, it is coerced to 0 == 0 (by rule #5) which results in true.

This particular case is somewhat tricky because of false ~> 0 instead of '0' ~> true (as what might be expected). However, '0' is itself a truth-y value and the behavior can be explained with the above rules. To have strict truthy-falsey equality in the test (which is different than a strict-equality) without implicit conversions during the equality, consider:

!!'0' == !!false

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

why all falsy values in javascript aren't equal to false when tested for equality

The == operator has its own semantics. You're comparing behaviors that are not defined to be the same.

If you want to see how the normal "truthy/falsy" evaluation works, you should use !value or !!value instead of value == false or value == true:

if (!null) console.log("hi");
if (!NaN) console.log("hi");

why does [] == 0 return true while [] is true and 0 is false?

Remember that array is object and 0 is number.

And as "user2864740" told..

1) When you doing

!![] //--- returns true
!!0 //--- returns false

You are performing so called "ToBoolean" convertion

https://es5.github.io/#x9.2

Number

The result is false if the argument is +0, −0, or NaN; otherwise the
result is true.

Object ( our [] )

always true

2) But when you using == you performing so called "Equality Comparison"

https://es5.github.io/#x11.9.3

Here thins a little bit complicated but to understand what happens you have to remember that == do a type coercion ( so you can compare oranges to apples :) )

First of all compiler converts [] to some primitive type.

If Type(x) is either String or Number and Type(y) is Object, return
the result of the comparison x == ToPrimitive(y).

How ToPrimitive works is a matter of an article :), but's it easy to remember that closet primitive type to array is string. Array will be converted to empty string.

[].toString() === ""

So now we need to compare empty string and number 0

"" == 0   // true

Hmmm. So it's true. But why is that? Remember that when you compare with "Equality Comparison" number and string


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

So let's try to convert empty string to number

Number("") === 0

And in the end

0 === 0

I hope that's explains something :)

Why is 0 == true in JavaScript

0 == ''

The left operand is of the type Number.

The right operand is of the type String.

In this case, the right operand is coerced to the type Number:

0 == Number('')

which results in

0 == 0

From the Abstract Equality Comparison Algorithm (number 4):

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

Source: http://es5.github.com/#x11.9.3

Why (!a) and (a == false) are not equal?

The short answer:

!a converts a value to a Boolean.

a == false compares a value to a Boolean.

These are two different operations.


!a is equivalent to Boolean(a) ? false : true. Boolean(a) returns false if a is

  • undefined
  • null
  • 0
  • ''
  • NaN
  • false

In every other case it returns true.

What happens in a == false is a bit more evolved, but not that complicated. The most important thing that happens is that false is converted to a number, so you are actually comparing a == 0. But undefined is treated in a special way in the comparison algorithm. It's not converted to any other type, so the algorithm simply returns false.

I wrote the following interactive tool for a JavaScript course which shows you which steps of the algorithm are performed when comparing two values:

Sample Image


Similar questions:

  • In JavaScript, why is "0" equal to false, but when tested by 'if' it is not false by itself?
  • Why does ('0' ? 'a' : 'b') behave different than ('0' == true ? 'a' : 'b')
  • JavaScript: What is the difference between `if (!x)` and `if (x == null)`?
  • Why "" == "0" is false in javascript?

Why does ('0' ? 'a' : 'b') behave different than ('0' == true ? 'a' : 'b')

First, for completeness:

('0' ? 'a' : 'b') 

is 'a', because '0' is a non-empty string, which always evaluates to true:

String: The result is false if the argument is the empty String (its length is zero);
otherwise the result is true.


Now to '0' == true.

Two type conversions will take place here. We can follow this in the specification, section 11.9.3, The Abstract Equality Comparison Algorithm.

The operands are denoted as x and y (x == y).

In our case, x is a string ('0') and y is a Boolean (true). Hence step 7 is executed:

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

When booleans are converted to numbers, the following conversion takes place:

Boolean: The result is 1 if the argument is true. The result is +0 if the argument is false.

Now we have

'0' == 1

which matches the condition in step 5:

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

How strings are converted to numbers is more complex but of course can also be found in the specification.

So the final comparison is

0 == 1

which is false (step 1. a. vi.)

Boolean Value of Zero

Yes, it appears that value is a string. And while the number 0.00 will evaluate to false, the string "0.00" evaluates to true.

The solution is to first convert the string to a number, and then perform the same test.

value = Number(value);
if (isVariance && value)
tableCell.addClass('NonZeroVariance');

EDIT:

The reason that the string "0.00" evaluates to true, is because: The result is false if the argument is the empty String (its length is zero); otherwise the result is true. - http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/



Related Topics



Leave a reply



Submit