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

The output of this code is: fail. Why?

cdxf
  • 5,501
  • 11
  • 50
  • 65
  • 4
    `(![]+[])[+[]]` is "f" (the first char from "false"), `(![]+[])[+!+[]]` is "a", etc. – Mauricio Scheffer Nov 13 '10 at 04:37
  • 1
    You should change the title to "Explain why this works" instead of "What is this?" - the What answer is evident. People will be less likely to close the question if it's worded better. – John K Nov 13 '10 at 04:38
  • 4
    @Snoob: as you said, you can test each expression on your browser. Try `alert(![]+[])` then `alert(+!+[])` and you'll see. – Mauricio Scheffer Nov 13 '10 at 04:45
  • @Mauricio Scheffer: (![]+[])[+!+[]] = 'false'[0] right?.But why ![]+[] = 'false' and why +!+[] = 0 ? – cdxf Nov 13 '10 at 04:49
  • 2
    @snoob Type coersion - the `+` there turns an empty array into a number. The `!` in front of the `[]` turns it into a boolean, and so on. – Yi Jiang Nov 13 '10 at 04:51
  • 2
    @Snoob: it uses `+` to convert stuff to int and `!` to convert to boolean. – Mauricio Scheffer Nov 13 '10 at 04:55
  • http://patriciopalladino.com/blog/2012/08/09/non-alphanumeric-javascript.html – Bergi May 30 '15 at 20:07

1 Answers1

143

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

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 21
    Where does the "i" come from? – Josh Stodola Nov 13 '10 at 05:00
  • 5
    @Snoob, because `+[]` produces zero, and `0` is not truthy, therefore in Boolean context it will yield `false` and the Logical NOT operator negates it: `!+[]` => `!0` => `!false` => `true` – Christian C. Salvadó Nov 13 '10 at 05:02
  • 6
    @rlemon, there's no `int` data type on the language, in fact all numbers are double-precision 64-bit format (IEEE 754 values), even though some operators work internally with Integer values (like the bitwise operators) the result is always a double. The `'i'` comes in this example from `undefined`, but it could come from `Infinity` for example: `(+!+[]/+[+[]]+[])[!+[]+!+[]+!+[]]` => `(1/0+'')[3]` => `(Infinity+'')[3]` => `'i'` – Christian C. Salvadó Sep 23 '11 at 15:07
  • 7
    @JoshStodola Well, ~3 months later, a further clarification. The "i" in this case comes from "undefined", yes, but there's another trick involved here. The code concatenates "false" to "undefined" to form `"falseundefined"`(constructed using: `[![]]+[][[]]`) in which the index of "i" is 10. `+!+[]+[+[]]` gives `"10"`. This is used to extract the "i"(String indices can be used in javascript if they can be coerced to integers apparently). The final construct which produces it is: `([![]]+[][[]])[+!+[]+[+[]]]` – entropy Dec 29 '11 at 09:44