javascript - Why and how does ([![]]+[][[]])[+!+[]+[+[]]] evaluate to the letter "i"? -
this question has answer here:
- why ++[[]][+[]]+[+[]] return string “10”? 8 answers
- (![]+[])[+[]]… explain why works 1 answer
while reading this article posted on dzone found snippet of javascript posted on twitter marcus lagergren.
the following code apparently prints string "fail"
(![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]];
this involves implicit type casting , i'm trying understand how line interpreted.
i've isolated each character
(![]+[])[+[]]
prints"f"
(![]+[])[+!+[]]
prints"a"
([![]]+[][[]])[+!+[]+[+[]]]
prints"i"
(![]+[])[!+[]+!+[]]
prints"l"
i've managed break down expressions returning each letter apart "i"
letter "f"
![]
empty array object, according ecmascript documentation, point 9.2 evaluates true
when converted boolean
false
false+[]
per point 11.6.1 both arguments of binary +
operator converted string, therefore "false"+""
, evaluates "false"
+[]
unary plus operator causes tonumber
conversion followed toprimitive
conversion if argument object
. result of such conversion determined calling [[defaultvalue]]
internal method of object. in case of empty array, defaults 0
. (ecmascript documentation, sections: 11.4.6, 9.3, 9.1 )
"false"[0]
we're accessing character @ index 0
, hence "f"
letter "a"
same story, difference here additional conversions in part in square brackets (which evaluates number point @ character in string "false"
), triggered use of unary +
, !
operators.
+[]
evaluates 0
, explained above.
!0
evaluates true
defined in section 9.2 , section 11.4.9. first, 0
converted boolean false
, operator inverts value.
+true
again, unary plus triggers tonumber
conversion, returns 1
binary true
(section 11.4.6 , 9.3)
"false"[1]
returns second character in string, "a"
letter "l"
!+[]
evaluates true
explained above
true+true
using binary +
on primitives triggers tonumber
conversion. in case of true, result 1
, 1+1
equals 2
"false"[2]
- self explanatory
letter "i"
what leaves me stumped letter "i"
. can see second part (in square brackets) evaluates string "10"
, first part (in parentheses) returns "falseundefined"
i can't make heads or tails of how happening. explain step step? magic happens square brackets? (arrays , array access)
if possible, i'd each step contain link underlying ecmascript rules.
what find cryptic part: [][[]]
your cryptic part isn't cryptic if rewrite little:
[]['']
[]
coerced string because isn't integer, you're looking property of []
name ''
(an empty string). you'll undefined
, there no property name.
as actual letter, break expression 2 main components:
- the string
([![]]+[][[]])
:[![]]
[false]
.[][[]]
undefined
.- add them ,
"falseundefined"
.
- and index:
[+!+[]+[+[]]]
. whitespace , parentheses make operations clearer:[+(!(+[])) + [+[]]]
:[+[]]
[0]
.+[]
coerces[]
integer,0
.!+[]
coerces0
boolean , negates it,true
.+!+[]
coercestrue
integer,1
.- add them together, ,
["10"]
.
when using string access properties of array , string happens element of array, string coerced integer , actual element of array:
> [1, 2, 3]["0"] 1 > [1, 2, 3]["1"] 2
so final result is:
> "falseundefined"["10"] "i"
read this answer explanation of [false] + undefined
part.
Comments
Post a Comment