Why +(!![]+!![]+!![]+!![]+[!![]+!![]]) yields 42?

JavaScript can produce the most unexpected results at times. For example, you may have heard before that:

NaN === NaN; // is false
[] == ![]; // is true
javascript?.js
Copied to clipboard!

Or that ('b' + 'a' + + 'a' + 'a').toLowerCase(); return β€œbanana”. These are just some of the seemingly meaningless results that JavaScript is capable of producing. However, JavaScript can do more than that. It looks like you can actually write code with only six different characters. These characters are:

! ( ) + [ ]
Copied to clipboard!

To better understand what role they represent, let’s have a look at a simpler example, the point of this tutorial. Why the long string of random characters results in 42? And more importantly, what’s the point of knowing all of this? The answer is data types and type conversion. Understanding the core principles of JavaScript will make you produce better code down the road. And the end of the tutorial, you’ll know as much about type conversion as you need to.


Producing 0 With Three Characters

Let’s take a step back and start from 0. How you can write down 0 with the above characters? This can be achieved relatively easy, with only three of them: +[]. But how come an empty array with a plus sign turns into 0? The unary plus operator that precedes the empty array, will try to convert its operand into a number if it isn’t already one. Falsy values will result in 0. For example, +false or +'' are also evaluated to 0. Just like +[].


Producing 1 With Five Characters

This means we can turn the boolean true β€” and some other truthy values β€” into ones. Therefore, to use the same set of characters, we need to cast the empty array into a true value. We know that ![] results in a false. By double negating an empty array, we can turn it into true:

!![] -> results in "true"
Copied to clipboard!

All we have to do now is use the unary plus operator to make it one:

+[]   -> results in 0
+!![] -> results in 1
Copied to clipboard!

Okay, so now we can produce zeros and one. But how do we get more numbers?


Producing Any Number With Six Different Characters

Now let’s try to produce 42 and basically any other number using the characters that have been mentioned at the beginning of the article. You may be thinking the solution is straightforward, we just have to produce ones, and add them together 42 times, right?

!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]
+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]
+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]
42.js
Copied to clipboard!

And that could work. However, this is way more characters than we need. There’s a simpler solution. Notice that there is no plus sign at the very beginning of the operation. You don’t need that, because of type conversion. Essentially, you are trying to add up true values and because of the unary plus operator, they are automatically converted into a number:

true + true + true + true ...
The previous example is equivalent to this
Copied to clipboard!

We can also do this with strings, however, the characters are concatenated instead:

'4' + '2'    // '42'
+('4' + '2') //  42
Copied to clipboard!

This means we basically only need to generate two values: a four and a two, add them together and cast them to an integer. We can write four and two as:

!![]+!![]+!![]+!![] // results in 4
!![]+!![]           // results in 2
Copied to clipboard!

However, if we try to connect them with the unary plus operator, we will only get 6, as they are already numbers, but we need strings. Again, we can use empty arrays to our advantage. If you try to add arrays together, you get a comma-separated string back:

[1, 2, 3] + [] // results in "1,2,3"
[] + []        // results in ""
Copied to clipboard!

That means we simply need to add an array to the numbers, and we get a string back, like so:

!![]+!![] + [] -> "2"
Copied to clipboard!

But since we are already trying to add two numbers together, we can simply wrap one of them into an array and add it to the other one:

[!![]+!![]] + [!![]+!![]] // results in "22"
!![]+!![] + [!![]+!![]]   // results in "22"
Copied to clipboard!

Both of them work fine, you can even omit wrapping the first value into an array, as we did in the example above. You only need one array to make JavaScript’s type conversion kick in. With the above, you are essentially writing 2 + [2], which will concatenate them and make them β€œ22”. To convert it back to an integer, you just have to use the unary plus operator once more. But to make it effective for the whole block, you need to wrap it inside parentheses, and you get the final formula:

// Returns 22
+(!![]+!![]+[!![]+!![]])
+(!![]+!![] + [!![]+!![]])

// Returns 42
+(!![]+!![]+!![]+!![]+[!![]+!![]])
+(!![]+!![]+!![]+!![] + [!![]+!![]])
42.js
Copied to clipboard!

Conclusion

Now you know the true nature of type conversion in JavaScript. Everything can be converted into other types, and this is why β€” and how β€” you can generate numbers from only 6 different characters. Since you are also able to generate strings, you can create more complex examples with this. For example, the below will alert 42 to your browser.

[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[])
[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+
(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+
[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])
[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]
+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])
[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]((!![]+[])
[+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([]
[[]]+[])[+!![]]+(![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+
[]]])[!![]+!![]+[+[]]]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[!![]+!![]+!![]]+
(!![]+[])[+!![]]+(!![]+[])[+[]])()(+(!![]+!![]+!![]+!![]+[!![]+!![]]))
alert.js
Copied to clipboard!

This was generated using jscrew.it. If you want to experiment with type conversion furthermore, I highly recommend checking out the site.

Do you know other weird behaviors of JavaScript that make you scratch your head? Let us know in the comments below! Thank you for reading through, happy coding!

The Curious Case of Banana in Javascript
Remove ads
Remove ads

πŸ“š Get access to exclusive content

Want to get access to exclusive content? Support webtips with the price of a coffee to get access to tips, checklists, cheatsheets, and much more. β˜•

Get access Support us
Remove ads Read more on
Remove ads
Remove ads
πŸŽ‰ Thank you for subscribing to our newsletter. x