8

Consider empty JavaScript array:

var a = [];
alert(a == false); // shows true
alert(!a); // shows false!

How to explain this? What are the rules?

Evgenyt
  • 10,201
  • 12
  • 40
  • 44
  • 1
    possible duplicate of [Why do alert(!!"0") and alert(false == "0") both output true in JavaScript](http://stackoverflow.com/questions/4567393/why-do-alert0-and-alertfalse-0-both-output-true-in-javascript) – SLaks Jan 07 '11 at 14:25
  • 1
    Thanks for pointing. But not exactly, I ask for generic rules. – Evgenyt Jan 07 '11 at 14:35
  • 2
    When it comes to the loose `==` operator, the rules aren't so generic. You should read through the Abstract Equality Comparison Algorithm referenced by [this answer](http://stackoverflow.com/questions/4626361/javascript-type-casting/4626420#4626420). – user113716 Jan 07 '11 at 14:39
  • Or, if you want to keep things simple, just avoid type coercion altogether. There may be some good use cases for coercion (`==`), but as a general rule, you can just avoid it (`===`). And then, you can build on that rule, and add exceptions where you do want to coerce. – Šime Vidas Jan 07 '11 at 17:18
  • **see also:** http://stackoverflow.com/questions/24318654 – dreftymac Jun 20 '14 at 01:44

5 Answers5

13

From http://forums.whirlpool.net.au/archive/966449:

a == false:

In this case, the type of the left-hand side is object, the type of the right-hand side is boolean. Javascript first converts the boolean to a number, yielding 0. Then it converts the object to a "primitive", yielding the empty string. Next it compares the empty string to 0. The empty string is converted to a number, yielding 0, which is numerically equal to the 0 on the right-hand side, so the result of the entire expression is true.

See §11.9.3 of the ECMAScript spec for all the gory details.

(!a):

In this case Javascript converts the object to the boolean true, then inverts it, resulting in false.

Ryan Li
  • 9,020
  • 7
  • 33
  • 62
  • here's a direct link to the afore-mentioned ECMA spec: http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3 – JKirchartz Feb 23 '15 at 19:32
8

The ! operator checks whether its operand is "falsy".

The following are true:

  • !false
  • !0
  • !null
  • !NaN
  • !undefined
  • !""

The == operator checks for loose equality, which has nothing to do with falsiness.

Specifically, a == b will convert to operands to numbers, then compare the numbers.
Strings containing numbers convert to the numbers that they contain; booleans convert to 0 and 1.
Objects are converted by calling valueOf, if defined.

Thus, all of the following are true:

  • "1" == 1
  • "0" == false
  • "1" == true
  • "2" != true
  • "2" != false
  • ({ valueOf:function() { return 2; } }) == 2
  • ({ valueOf:function() { return 1; } }) == true
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
5

The == operator when one of the operands if Boolean, type-converts the other to Number.

[] == 0;

Is equivalent to:

0 == 0;

You can see the complete details of The Abstract Equality Comparison Algorithm on the specification.

As you can see, an empty array object, when converted to Number, produces 0:

+[]; // 0
Number(0);

This is really because its toString method produces an empty string, for example:

[].toString(); // ""

+""; // 0
Number(""); // 0
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
1

When comparing an object to a primitive value via the == operator, the object coerces into an primitive value itself (number or string). In this case [] coerces into 0, then false coerces into 0:

[] == false
0 == false
0 == 0

which is true.

The ! operator coerces into boolean and then inverts the value. [] into boolean is true (like with any object). Then invert to become false

![]
!true
false
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
0

Not sure if this answers the question, but there is a new library for getting around all of Javascript's Typecasting weirdnesses:

Typecast.js

In a sentence, Typecast solves all the simple problems, so you can focus on the big ones. Typecast fixes what's wrong with Javascript by creating a complete platform for strongly-typed variables in Javascript.

BishopZ
  • 6,269
  • 8
  • 45
  • 58