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
- 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:
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
Convert Base64 String to Arraybuffer
Using Jquery's Ajax Method to Retrieve Images as a Blob
Invariant Violation: Objects Are Not Valid as a React Child
Define Global Variable with Webpack
Find Out Whether Chrome Console Is Open
Using Rails 3.1, Where Do You Put Your "Page Specific" JavaScript Code
Navigator.Geolocation.Getcurrentposition Sometimes Works Sometimes Doesn'T
Multi-Row Insert with Pg-Promise
Angularjs "Controller As" Syntax - Clarification
What's the Significant Use of Unary Plus and Minus Operators
Javascript: Filter() for Objects
How to Listen to a "Style Change" Event
Recurring Events in Fullcalendar
How Does Facebook Disable the Browser's Integrated Developer Tools
Webdriver Click() VS JavaScript Click()
How Does JavaScript's Sort() Work
Issue in Returning Data Retrieved from Db Queries Called in the Loop