Can anyone explain why here a = [] ? 1 : 2
a will be equal to 1 and here b = [] == true ? 1 : 2
b will be equal to 2

- 730,956
- 141
- 904
- 1,278

- 1,236
- 2
- 12
- 27
-
The answer will be very similar to my answer here: [Why does ('0' ? 'a' : 'b') behave different than ('0' == true ? 'a' : 'b')](http://stackoverflow.com/questions/7496727/why-does-0-a-b-behave-different-than-0-true-a-b). You just have to follow the same steps for arrays. – Felix Kling Jun 08 '12 at 15:30
-
1Because `[]` is not null and not `true` either. – UltraInstinct Jun 08 '12 at 15:31
6 Answers
A very similar case is handled in Why does ('0' ? 'a' : 'b') behave different than ('0' == true ? 'a' : 'b').
In short:
When you have a single value that is evaluated in a boolean context, it is passed to
ToBoolean
to be converted to a boolean value.If you compare values with
==
though, the algorithm in section 11.9.3 of the ECMAScript specification takes place. In this algorithm, both operands are converted to either strings or numbers and these values are compared.
More detailed explanation
a = [] ? 1 : 2
The condition is converted to a boolean by calling ToBoolean(GetValue(lref))
. Now I assume that for objects, GetValue
just returns the object itself and all objects evaluate to true
.
Since arrays are just objects, the result of this expression is 1
.
b = [] == true ? 1 : 2
As already said, quite some type conversion is going on here.
First, true
is converted to a number:
7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
false
is converted to 0
and true
is converted to 1
.
So we have
[] == 1
Then step 9 applies:
9. If Type(x) is Object and Type(y) is either String or Number,
return the result of the comparison ToPrimitive(x) == y.
That means []
is converted to a primitive value (string or number). If you follow the ToPrimitive
function (and section 8.12.8), you'll find out that arrays are converted to strings, by concatenating their elements with ,
. Since an empty array as no elements, the result is an empty string.
So we end up with
"" == 1
Then step 5 applies:
5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
An empty string is converted to 0
, hence 0 == 1
is false
and the conditional operator returns 2
.

- 1
- 1

- 795,719
- 175
- 1,089
- 1,143
-
+1 A better (and more correct) explanation of what I was trying to get at. – geekchic Jun 08 '12 at 15:44
Because an array is an object, and when an object is evaluated in the context of a boolean comparison, it is "truthy", but not exactly true.

- 6,912
- 2
- 30
- 49
In the first example the array is being converted to a Boolean which yields true as it's not null, undefined, "", 0 or false.
In the second example you're getting a type conversion because of the equals operator. From mdn:
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.
Tried the following in the console:
Number(true) //gives 1
Number([]) //gives 0
So when converted to numbers these are not equal.

- 1,526
- 1
- 11
- 21
In a = [] ? 1 : 2
, it returns 1
if []
is not null
or undefined
.
In b = [] == true ? 1 : 2
, it would return 1
if []
is true
, but it's not, so it returns 2
.

- 11,270
- 8
- 53
- 67
The first is an assignment and thus has to fall through to true (but DOESN'T equate anything). Equating empty to true will be false.

- 6,343
- 16
- 19
Because initialising an array with []
returns true and [] == true
does not :-)

- 2,864
- 1
- 16
- 27