Maksims Kitajevs
Maksims Kitajevs

Reputation: 225

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

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

Answers (4)

Azder
Azder

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:

  • operator ! uses a defined set of falsy values (false,0, '' or "" (empty string), null, undefined, NaN) all else is truthy
  • operator == uses per type conversions not regarding if the original value is considered falsy, so after being converted, it may well be truthy

Upvotes: 1

Felix Kling
Felix Kling

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:

enter image description here


Similar questions:

Upvotes: 10

Tamas Hegedus
Tamas Hegedus

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:

  1. ReturnIfAbrupt(x).
  2. ReturnIfAbrupt(y).
  3. If Type(x) is the same as Type(y), then Return the result of performing Strict Equality Comparison x === y.
  4. If x is null and y is undefined, return true.
  5. If x is undefined and y is null, return true.
  6. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
  7. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
  8. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
  9. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
  10. If Type(x) is either String, Number, or Symbol and Type(y) is Object, then return the result of the comparison x == ToPrimitive(y).
  11. If Type(x) is Object and Type(y) is either String, Number, or Symbol, then return the result of the comparison ToPrimitive(x) == y.
  12. Return false.

So for undefined == false: first we hit #9, and then #12, which evaluates to false.

Upvotes: 1

Lazar Ljubenović
Lazar Ljubenović

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

Related Questions