1

If you try to run following code you will see that
(![]+[])[+1] returns "a";
(![]+[])[+2] returns "l";
(![]+[])[+3] returns "s".
And so on. Why?

João Paulo Macedo
  • 14,919
  • 4
  • 30
  • 40
windvortex
  • 55
  • 3
  • 8
    Have you *at least* tried looking at what the individual parts of those expressions evaluate to? – Pointy Aug 21 '14 at 13:54
  • 2
    (![]+[]) is "false" => (![]+[])[+2] is "l", not "1" (one). – ROMANIA_engineer Aug 21 '14 at 13:54
  • 1
    `(![]+[])` evaluates to `"false"` and then you are simply accessing the characters of the string as an array. The reason why is left as an exercise to the reader. :) – dee-see Aug 21 '14 at 13:54

3 Answers3

12

(![]+[]) returns "false" in javascript. The +1 takes the letter at index 1. Therefore a.

Danny
  • 7,141
  • 8
  • 42
  • 68
10

Let's break it down piece by piece.

> ![]
false

Array literals are truthy even when empty, so the negation is boolean false.

> ![]+[]
"false"

Adding a boolean (the false from above) to an empty array results in the string version of "false", thanks to JS's strange rules for adding arbitrary objects.

> (![]+[])[1]
"a"
> (![]+[])[3]
"s"
(etc)

is equivalent to:

> "false"[1]
"a"
> "false"[3]
"s"

and so on -- indexing a string returns the character at that index.

Finally,

> +[]
0

so

> "false"[+[]]
"f"

and putting it all together:

> (![]+[])[+[]]
"f"
dee-see
  • 22,825
  • 5
  • 58
  • 88
kevingessner
  • 17,869
  • 5
  • 40
  • 62
1

You're indexing the result of the first expression as a string.

(![]+[]) => false

false[1] => "false"[1] => a

ajm
  • 19,099
  • 3
  • 31
  • 37
  • `(![]+[])` returns the string false. `false[1]` returns `undefined`, there is no conversion to string that would happen. – dee-see Aug 21 '14 at 13:57