# Some common misunderstandings in JavaScript

## Jun 26, 2019 11:47 ยท 744 words ยท 4 minute read

Disclaimer: This article talks about how some parts of the JavaScript language can be misunderstood by developers leading to an unexpected results.

Do you know why the following code will end up **charging $5** to the **user**? ๐จ

```
const discount = (amount, quantity) => amount - quantity;
let amount = 1.5
amount = discount(amount,1.2) // 1.5 - 1.2 = 0.3
amount = discount(amount,0.3) // 0.3 - 0.3 = 0
return parseInt(amount) // 0
```

The `discount`

function subtracts the discount amount from the total amount we have to pay.

The user is lucky as we’ll discount the total amount he had to pay. However, somehow, we end up charging $5 to him. ๐

This unexpected behavior comes from two different issues tied to the language.

The first one appears when we subtract `1.5 - 1.2`

, the expected result would be `0.3`

but the real result is `0.30000000000000004`

.

This small error, known as **rounding error**, comes from how JavaScript processes the *floating-point*.
You can read more in this excellent article of **Brian Rinaldi**.

Because of this small issue, when we subtract, `0.3`

we wind up with `0.00000000000000004`

instead of `0`

, and here is when the second issue appears.

What we would expect from `parseInt`

is to leave the value untouched, however, this is not happening.
Once you execute `parseInt(1.5-1.2-0.3)`

the result will be 5. ๐

Let’s delve in what’s happening here.

The `parseInt`

function is doing __one thing under the hood__. It transforms the number to its string representation before parsing it.

The funny thing here is that given 7 decimals or more the string representation changes from `0.0000001`

to `1e-7`

and, from here, everything __gets messed up__.

The `parseInt`

function was designed to handle not only decimals but octal and hexadecimal values too. In order to do that it returns the first number of the string instead of failing.

The operation`(1.5-1.2-0.3)`

it’s displayed as `5.551115123125783e-17`

. If we parse this to an integer it will consider only the first number of the string `5.551115123125783`

and it will remove all decimals.
In that way we’ll end up with `5`

, which is exactly what we charged to our customer.

Let’s see another example:

```
const sum = (a,b) => a + b;
const cutDecimals = (num) => num.toFixed(2)
const sumItemPrices = itemPrice => parseFloat(itemPrice.map(cutDecimals).reduce(sum,0));
const itemPrices = [1,3,1.345]
return sumItemPrices(itemPrices)
```

The expected output for this function should be `1+3+1.54 = 5.34`

but instead the value returned it’s `1.003`

.

This particular issue is locaten in the `toFixed`

funtion. This function is meant to be a decorative function returning a `string`

value instead of a `number`

(a bit counterintuitive don’t you think?).

Because of that when we `cutDecimals`

of our array of numbers `[1,3,1.345]`

it get’s transformed into an array of strings like this `["1","3","1.345"]`

therefore when we apply the sumation function to every single value instead of summing we are concatenating the values ending up with the following string `"01.003.001.34"`

. If we try to `parseFloat`

this string it will stop on the second dot as will consider the rest as unvalid characters and it will return `1.003`

.

Now let’s talk a bit about types. Let’s see this function:

```
const isNumber = num => typeof num === "number";
```

They look reasonable and correct but it’s not, in fact, have an edge case in which don’t behave as expected.

```
isNumber(1) // -> true, it's ok
isNumber("x") // -> false, it's ok
isNumber(parseInt("x")) // -> true, ???
```

What’s happening here is that `parseInt("x")`

returns `NaN`

(not a number) and the type of “not a number” is a number, which again can be kind of confusing.

And you can find more thinks in the language that can go against your common sense like these ones:

```
typeof null // -> "object"
typeof [] // -> "object"
isNaN([]) // -> false
undefined == null // -> true
```

As we can see, in javascript, a very “innocent” code can became a disaster if we don’t really know the insights of what we are doing and even if we know it’s easy to make mistakes.

For that reason we created a small open-source library called keyu which pretends to relieve developers from this hassle. For now it’s a very small and humble library but with your collaboration can be a good reference for the rest.

If you are interested to contribute you can find the source code here

If you

feel the pain,contributeto it. If youlikeit,shareit and if youdon’t, please,criticizeit.