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

Javascript

Javascript Problem Overview


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

The output of this code is: fail. Why?

Javascript Solutions


Solution 1 - Javascript

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)).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncdxfView Question on Stackoverflow
Solution 1 - JavascriptChristian C. SalvadóView Answer on Stackoverflow