JS WTF 🦄 with Math by@ferreiratiago

September 26th 2017 14,077 reads

WHAT?`max`

is not bigger than `min`

? **NO** 😱 but there’s a reason for it.

By definition `Math.max([value1[, value2[, ...]]])`

returns the largest of the given numbers. However, when no arguments are provided it returns the **minimum possible value, **which is `-Infinity`

.

As you guessed `Math.min()`

returns `Infinity`

when no arguments are provided, i.e. the **highest possible value**.

Therefore, when comparing `Math.max() > Math.min()`

is not even fair.

It’s not fair.

`-Infinity`

its way lower than `Infinity`

.

This is not a problem of JS to be fair. This is **floating point math**.

Computers can only natively store integers, so they need some way of representing decimal numbers. This representation comes with somedegree of inaccuracy. That’s why, more often than not,`.1 + .2 != .3`

— 0.300000000000004.com

The problem lies on the way machines store numeric values (i.e. **binary representation**.) In the case of **integer values**, only integers that can be represented as number times the power of two can be exactly represented.

As for **rational numbers **(such as `0.1`

, which is `1/10`

) only values whose the denominator can be represented as a power of two can be exactly represented.

Although `0.1`

and `0.2`

can be exactly represented in `base 10`

the same is not true for `base 2`

. **When this happens our machines create an approximation of their true value **(which results into a repeating value).

**Therefore, the result of ****0.1 + 0.2**** would be a repeating value.**

Which in `base 10`

is represented by `0.30000000000000004`

.

The `+`

operator has a different behaviour in each example.

It behaves as an **addition operator**** **for the expression `[] + {}`

, and as **unary operator** for the expression `{} + []`

.

When interpreting the expression `[] + {}`

JS identifies an addition operation but before adding both operands it converts them to **primitives**. This is done by executing the static method `.toString()`

.

As a result we end up with the operation `'' + '[object Object]'`

.

Only at this stage JS knows that the addition operator `+`

has the purpose of **concatenating strings**. And the final value of `'[object Object]'`

is returned.

Next!

For the expression `{} + []`

, the first operant is a pair of curly brackets (i.e. *an empty block*.) This empty block means **“nothing to do”**.** **Therefore JS moves forward on executing the expression.

When reaching the `+`

operator it behaves as an **unary operator** because it has no left operand. Through coercion `[]`

is translated into `0`

.

Here, the `+`

** **operator behaves as an **additional operator **and adds both operands. However before it can do that it needs to convert them `ToNumber`

.

By definition, `ToNumber`

returns **1** if the argument is **true**,** 0** if the argument is **false**.

For this reason, our expression `true + true`

translates into `1 + 1`

, which is 2.

*Spoiler alert: **It’s** **coercion** again *😎

Here, it may be useful to go step-by-step for both examples.

`1 < 2 < 3`

- Because JS interprets and executes the expressions from
**left to right**, it will run the expression`1 < 2`

first, therefore`true < 3`

; - Next,
**coercion**,`ToNumber(true) < 3`

which translates into`1 < 3`

; - Return
`true`

(because`1`

is lower than`3`

);

`3 > 2 > 1`

- Because
`3 > 2`

is`true`

then`true > 1`

; `ToNumber(true) > 1`

translates into`1 > 1`

(**coercion**again 👌);- Return
`false`

(because`1`

is not higher than`1`

);

By definition **the** **addition operator** performs either **string concatenation** or **numeric addition**.

**When one of the operands is a string, JS converts the other operand to a string and returns the concatenation of both**. In the case of `'5' + 3`

, because the left operand is a string the final result is the concatenation of both`'5'`

and `ToString(3)`

, which is `'53'`

.

**The subtraction operator** performs a **subtraction** with the two operands.

However, when an operator is not of the type `Number`

it is converted `ToNumber`

. For that reason, the string `'5'`

is converted into the number `5`

to which is subtracted `3`

. The final result is `2`

.

*If you find any weirdness that should be here, please let me know *👐

- Maggie Neterval for her talk
- The mind blowing 0.30000000000000004.com
- Oracle for their — What Every Computer Scientist Should Know About Floating-Point Arithmetic
- Kyle Simpson for his video and book
- MDN Documentation
- Chris Pratt for the Guardians of the Galaxy and the gifs
- Hacker Noon for publishing ❤️

*Be sure to check out my other articles on JS WTF*