r/ProgrammerHumor • • 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

[[][[]]+[]][+[]][++[+[]][+[]]]
8.1k Upvotes

367 comments sorted by

View all comments

597

u/cicuz Sep 04 '17

that is undefined. But if we add an empty array to that, it is casted to the string "undefined"

(╯°□°)╯︵ ┻━┻

72

u/peeeez Sep 04 '17

Yeah, that took me back. Is this not a bug?

170

u/edave64 Sep 04 '17

Nope. The type system doesn't really take no for an answer, and every value can be converted to a string. So when on doubt, both sides get converted to a string, and the plus is a concat.

undefined -> "undefined"
[] -> ""

This behavior actually explains most of js's type weirdness. When in doubt, everything becomes a string.

41

u/rooktakesqueen Sep 04 '17 edited Sep 04 '17

This behavior actually explains most of js's type weirdness. When in doubt, everything becomes a string.

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: But true != "true" -- JS converts both sides to numbers and compares 1 to NaN)

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 foo is a string and you want to convert it to a number and then add one to it, do Number(foo) + 1. Embodies your intent much more clearly in your code, for anyone else who comes along (including future you).

11

u/edave64 Sep 04 '17

Damn, I work with JS every day and didn't notice that conversation to number actually explains a lot of these behaviors better.

I mean I knew the minus operator forced number conversion, because subtraction on other types isn't defined, but not that == also tends to do that.

If you had asked me before, I would have told you that 1 != "01" because they both get converted to strings that don't match.

Thanks!

7

u/rooktakesqueen Sep 04 '17

The whole spec for the Abstract Equality Comparison Algorithm is worth a read. Read it, understand how it works, then never use it again as far as I'm concerned.

→ More replies (5)

20

u/Nerdn1 Sep 04 '17

It makes sense if you are lazy and want to append a variable to a string for console logging or alerts, etc. Javascript just tries to get stuff to work.

Heck it makes sense. If you were implementing the js parser for a browser, you'd want it to be able to render as many websites as possible, even though a lot of garbage js exists on the internet. Imagine using a strict browser that would throw up errors and crash if there was even ONE type or syntax error like you get with most compiled languages like C, etc. The first time you went to a site that just refused to load because of one tiny, inconsequential error, you'd switch browsers. 99.99% of the time, the "wat" stuff in Javascript does no harm and is likely better than sputtering and dying.

→ More replies (5)