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
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:
! ( ) + [ ]
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"
All we have to do now is use the unary plus operator to make it one:
+[] -> results in 0
+!![] -> results in 1
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?
!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]
+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]
+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]
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 ...
We can also do this with strings, however, the characters are concatenated instead:
'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:
!![]+!![]+!![]+!![] // 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:
[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:
!![]+!![] + [] -> "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:
[!![]+!![]] + [!![]+!![]] // 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:
// Returns 22
+(!![]+!![]+[!![]+!![]])
+(!![]+!![] + [!![]+!![]])
// Returns 42
+(!![]+!![]+!![]+!![]+[!![]+!![]])
+(!![]+!![]+!![]+!![] + [!![]+!![]])
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.
[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[])
[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+
(!![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+
[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])
[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]
+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])
[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+(!![]+[])[+!![]]]((!![]+[])
[+!![]]+(!![]+[])[!![]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([]
[[]]+[])[+!![]]+(![]+[][(![]+[])[+[]]+(![]+[])[!![]+!![]]+(![]+[])[+!![]]+(!![]+[])[+
[]]])[!![]+!![]+[+[]]]+(![]+[])[+!![]]+(![]+[])[!![]+!![]]+(!![]+[])[!![]+!![]+!![]]+
(!![]+[])[+!![]]+(!![]+[])[+[]])()(+(!![]+!![]+!![]+!![]+[!![]+!![]]))
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!
Rocket Launch Your Career
Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies: