Why and how does ([![]]+[][[]])[+!+[]+[+[]]] evaluate to the letter "i"? [duplicate]
Your cryptic part isn't all that cryptic if you rewrite it a little:
[]['']
[]
will be coerced into a string because it isn't an integer, so you're looking for a property of []
with the name ''
(an empty string). You'll just get undefined
, as there is no property with that name.
As for the actual letter, break the expression up into the two main components:
- The string
([![]]+[][[]])
:-
[![]]
is[false]
. -
[][[]]
isundefined
. - Add them together and you get
"falseundefined"
.
-
- And the index:
[+!+[]+[+[]]]
. Some whitespace and parentheses will make the operations much clearer:[+(!(+[])) + [+[]]]
:-
[+[]]
is[0]
. -
+[]
coerces[]
to an integer, so you get0
. -
!+[]
coerces0
to a boolean and negates it, so you gettrue
. -
+!+[]
coercestrue
to an integer, so you get1
. - Add them together, and you get
["10"]
.
-
When using a string to access the properties of the array and the string happens to be an element of the array, the string is coerced into an integer and you get back the actual element of the array:
> [1, 2, 3]["0"]
1
> [1, 2, 3]["1"]
2
So your final result is:
> "falseundefined"["10"]
"i"
Read this answer for an explanation of the [false] + undefined
part.
([![]]+[][[]])[+!+[]+[+[]]]
has two parts :
([![]]+[][[]])
and the other which you found yourself.
![]
returns false
. Then we use [...]
to get the .toString()
behavior of +
.
([]+[]
is the same as [].toString()+[].toString()
)
the [][[]]
is undefined because we're trying to access the index []
(or [].toString()
, which is ''
) of []
which is undefined.
Sorry for the previous answered, I misread your comment totally.