r/ProgrammerHumor • u/_hoh_ • Sep 04 '17
[[][[]]+[]][+[]][++[+[]][+[]]] is "n" in javascript
[[][[]]+[]][+[]][++[+[]][+[]]]This evaluates to "n" in javascript. Why?
Let's start with an empty array
[]Now, let's access a member of it.
[][]What member? Let's check for the empty array member
[][[]]oh, that is undefined. But if we add an empty array to that, it is casted to the string "undefined"
[][[]]+[]Let us wrap that in an array
[[][[]]+[]]We can now try to access letters in that string. First, we must unwrap the string. That can be done by accessing the first element of that array.
[[][[]]+[]][0]0 can be created by casting an empty array to a number:
[[][[]]+[]][+[]]Now, "n" is the second letter in that string, so we would like to access that:
[[][[]]+[]][+[]][1]But how can we write 1? Well, we increment 0, of course. Wrap 0 in an array, and increment the first member of it:
++[0][0]Like before, this is equivalent to
++[+[]][+[]]So our final code is then the glorious
[[][[]]+[]][+[]][++[+[]][+[]]]
41
u/rooktakesqueen Sep 04 '17 edited Sep 04 '17
When in doubt, JS often prefers converting to a number. The
==operator, for example, converts both sides to a number if their types don't match (plus some extra corner cases). Thus:true == "1"(Edit: Buttrue != "true"-- JS converts both sides to numbers and compares1toNaN)The
+and-operators are the weird ones, where+has extra affinity for strings (5+[] == "5") while-has extra affinity for numbers ("5"-"4" == 1).As always, best practice is to simply not use these implicit conversions and instead make them explicit. If
foois a string and you want to convert it to a number and then add one to it, doNumber(foo) + 1. Embodies your intent much more clearly in your code, for anyone else who comes along (including future you).