Reputation: 225
Talk is cheap, I will show my code.
var a; // a = undefined
if(a == false){ // As I typed == not ===, a needs to be translated to boolean (undefined == false) but it doesn't
return false;
}
else {
return true;
}
// true
This returns true but I was sure that it would return false because undefined is the same as false when I'm using double equal.
Things came strange when I tried to use
if(!a){..} else {..};
// false
Here I got my false but till this moment I thought (!a) and (a == false) are absolutely equals.
Upvotes: 2
Views: 2544
Reputation: 4728
(!a) and (a == false) are absolutely equals.
you use two different operators and assume they are absolutely equals - never do this, there is a reason 2 different operators exists instead of 1.
Now, think of NaN
(as one example, others may apply). By definition NaN
is a falsy value but not false
value, so:
if(!NaN) {} // this will execute
if(NaN == false) {} // this will not execute
Why do you think this happens?
Because ==
operator does type coercion per type/value, thus NaN
doesn't coerce to false
, while others, like 0
may, but both will be considered falsy and converted to true
using !
Summed:
!
uses a defined set of falsy values (false
,0
, ''
or ""
(empty string), null
, undefined
, NaN
) all else is truthy==
uses per type conversions not regarding if the original value is considered falsy, so after being converted, it may well be truthyUpvotes: 1
Reputation: 816354
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:
Upvotes: 10
Reputation: 29906
You had a false assumption. x == false
does not coerect x
to boolean
. In fact, ==
has it's own equality table.
If you don't believe random blogposts, here is the spec:
7.2.12 Abstract Equality Comparison
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
- ReturnIfAbrupt(x).
- ReturnIfAbrupt(y).
- If Type(x) is the same as Type(y), then Return the result of performing Strict Equality Comparison x === y.
- 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 comparison x == ToNumber(y).
- If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
- If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
- If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
- If Type(x) is either String, Number, or Symbol and Type(y) is Object, then return the result of the comparison x == ToPrimitive(y).
- If Type(x) is Object and Type(y) is either String, Number, or Symbol, then return the result of the comparison ToPrimitive(x) == y.
- Return false.
So for undefined == false
: first we hit #9
, and then #12
, which evaluates to false.
Upvotes: 1
Reputation: 19754
The only correct answer is "that's the way it is". The source of your confusion is a feature of JavaScript called type coercion and different types of equality comprisons (==
, ===
in JavaScript).
There's an interesting table which tells you which comparisons will result to true
on JavaScript Equality Table.
The only two values which will give true
when ==
-compared with null
are null
and undefined
.
In other words, x == null
will be true
if and only if x
is null
or undefined
.
Upvotes: 2