(![]+[])[+[]]… Explain why this works

(![]+[])[+[]]… Explain why this works

alert((![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]);

The output of this code is: fail. Why?
By the way, (![]+[])[+!+[]] == ‘false'[1], right?. But why ![]+[] == “false” and why +!+[] == 1 ?

Solutions/Answers:

Solution 1:

As @Mauricio commented (![]+[])[+[]] is “f” (the first char of “false”), (![]+[])[+!+[]]) is “a”, etc…

How does it work?

Let’s examine the first character, ‘f’:

(![]+[])[+[]]; // 'f'

The first part of the expression—between parentheses—is composed by ![]+[], the first operand of the Addition operator is ![] and it will produce false, because an array object—as any other Object instance—is truthy, and applying the Logical (!) NOT unary operator, it produces the value false, for example.

![]; // false, it was truthy
!{}; // false, it was truthy
!0;  // true, it was falsey
!NaN;  // true, it was falsey

After it, we have the second operand of the addition, an empty Array, [], this is made just to convert the false value to String, because the string representation of an empty array is just an empty string, is equivalent to:

false+[]; // "false"
false+''; // "false"

The last part, the pair of square brackets after the parentheses, they are the property accessor, and they receive an expression, which is formed by the Unary Plus Operator applied to an empty array again.

What the Unary Plus Operator does is type conversion, to Number, for example:

typeof +"20"; // "number"

One more time, this is applied to an empty Array, and as I said before, the String representation of an Array is an empty string, and when you convert an empty string to Number, it is converted to zero:

+[]; // 0, because
+[].toString(); // 0, because
+""; // 0

Therefore we can “decode” the expression to in some steps:

(![]+[])[+[]];
(false+[])[+[]];
(false+'')[+[]];
(false+'')[0];
('false')[0];  // "f"

Note that accessing characters by using the bracket notation on String values was not part of the ECMAScript 3rd. Edition Specification, (that’s why the charAt method existed).

However this kind of “index properties” that represent the characters of a string were standardized on ECMAScript 5, and even before the standardization the feature was available in a good number of browsers (even in IE8 (standards mode)).