Little shenanigans of JavaScript
Tags: beginners, javascript, webdev, codenewbie
Published: 2020-05-08 17:33:38

Even after working with JavaScript for over three years now, it never fails to surprise me with its little tricks and sly outputs. But these very secrets and surprises makes me fall in love with this language, all over again. Everytime!🤩

Some people don't find these shenanigans hindering their practical work. But believe me, I avoided a production bug (which would have made my fancy looking UI go berserk) by serendipitously testing a sample dataset that unveiled yet another sly trick of JS arithmetic. 

And so, finally, I decided to compile a few such tricks here in this post. Hope you have fun discovering something new. 

### 1. Adding float numbers

```javascript
console.log(0.1 + 0.2)
console.log(0.1 + 0.2 - 0.2)
console.log(0.1 + 0.7)
console.log(0.2 + 0.7)
```

Run the above code in your developer console and be like WTF!! How can you mess up something as simple as this JS??

If you are too lazy to check for yourself, this is what the output looks like:

```javascript
0.30000000000000004
0.10000000000000003
0.7999999999999999
0.8999999999999999
```

The reason behind this behavior is the accuracy with which JS stores float values.

I was working on a report visualization project where I had to display the total bounced email percentage by adding up soft-bounce and hard-bounce. Since this was to be displayed in a compact UI, displaying 0.30000000000000004% instead of 0.3% would make my page go insane (much to the amusement of the user). Fortunately, I realised it as soon as I tested it and fixed it.

So, how do we fix this?
```javascript
let a = +(0.1 + 0.2).toFixed(1)
let b = +(0.1 + 0.7).toFixed(2)
```

Explanation: 
`toFixed(num)` converts the `float` to `string` with precision of `num` after decimal point. The unary operator converts the `string` back to `number`. If you are using this to display somewhere in your UI, you are pretty much done after 'toFixed'. If you are going to use it for further calculations, go ahead and convert it to `number`.

But note: 
"0.30" in string when converted to number becomes 0.3. So, don't be surprised.

### 2. Silent conversions

I don't see why someone would write a code like this, but let's assume you somehow landed with these set of numbers (say from an API call response) and are performing an operation as below:

```javascript
console.log(022 === 018) //true
console.log(023 === 019) //true
console.log(010 === 008) //true
//if i keep going on, you will soon see the pattern
```

Common, don't be lazy and give this a shot in your console. The best way to learn JS is to befriend that F12 of your browser. 
Most of you would have guessed what's happening here. But let me lay it down for you either way...
When JS sees 0 in the start of a number, it converts it to Octa. That explains 022, 023, 010 (you can experiment more). But wait! 8 and 9 are not valid numbers of the Octa Number System. Well, that's why they are converted to Decimal. 
And this explains 022 (18 in Decimal) even strictly matches with 018. 

### 3. Let's get Quirk-ier

There is no real-world example of this crazy expression, but I loved it so much that I decided to pop it in anyways. I came across this in [WTF-JS](https://wtfjs.com/) (quite apt!).

```javascript
console.log((!+[]+[]+![]).length)
// 9
```

Yes, the answer is 9! Whaaaaa 🤐
There was no way I was going to give up without finding out why! After a gazillion unsatisfying hypothesis, I finally made one that I am quite sure of, and here it is...

But before scrolling down for the solution, I urge you to try figuring out for yourself. Believe me, it's Merlin's Beard Satisfying!

Explanation:
First let's see what are we finding the length of, at first place?
```javascript
console.log(!+[]+[]+![])
// Ans: "truefalse"
//HOLY CHRIST!!!!
```
How on earth did JS do this??
Let's chop it down to three parts:
(!+[]) + ([]) + (![])

1. `!` alone is really nothing in JS. God knows why it took me so long to figure out... And soooo, 
`+[]` works as a unary operator on an empty object, which basically converts `[]` into Number. 
Since `[]` is an empty array, its numeric value is `0`.
So this is equivalent to `!0` == `true` (because Boolean of 0 is TRUE). 

2. `[]` is an empty array. Adding this with a boolean `true` converts both of them to string. So the stringified value of `[]` is an empty string `""`. Hence, so far we have `"true"`.

3. Now, the last one might be get a little tricky considering the first one in picture and if you are not aware of *falsy values* in JS. 

Here, `![]` is not the same as `!0`.
This time `[]` is NOT converted to number, but directly applied to `Boolean(![])` which is FALSE. 
There are only 8 falsy values in JS, find them [here](https://developer.mozilla.org/en-US/docs/Glossary/Falsy).

So all-in-all, this expression is equivalent to: 
```javascript
"true"+false
//"truefalse"
```

We know here on. string + boolean = string. So the result is `"truefalse"`. And the length of it is 9. 

DAMN! This felt GOOD! 🤸‍♂️

I will end the list for now. But I have way too many such examples. If you liked it, let me know and I will make this into a series. Also, if you have such examples which got you like- Whaaaaaa 👀 , do share it in comment section.