javascript - Why and how does ([![]]+[][[]])[+!+[]+[+[]]] evaluate to the letter "i"? -


this question has answer here:

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.
    • !+[] coerces 0 boolean , negates it, true.
    • +!+[] coerces true 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

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -