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

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

Understanding type conversion in and out
Ferenc AlmasiLast updated 2021 November 11 • Read time 5 min read
JavaScript can produce the most unexpected results at times. For example, you may have heard before that NaN is not equal to NaN. But why is that?
  • twitter
  • facebook
JavaScript

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

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

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:

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

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

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

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

Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScriptinfo Remove ads

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?

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

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:

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

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

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

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:

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

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:

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

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

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

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:

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

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:

Copied to clipboard! Playground
// Returns 22
+(!![]+!![]+[!![]+!![]])
+(!![]+!![] + [!![]+!![]])

// Returns 42
+(!![]+!![]+!![]+!![]+[!![]+!![]])
+(!![]+!![]+!![]+!![] + [!![]+!![]])
42.js

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.

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

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
  • twitter
  • facebook
JavaScript
Did you find this page helpful?
📚 More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Access 100+ interactive lessons
  • check Unlimited access to hundreds of tutorials
  • check Prepare for technical interviews
Become a Pro

Courses

Recommended

This site uses cookies We use cookies to understand visitors and create a better experience for you. By clicking on "Accept", you accept its use. To find out more, please see our privacy policy.