# 🤯 Weird JS (#1)

JavaScript is a "dynamically typed" language, meaning that it exists data types, but variables are not bound to any of them. Because of that, when we perform operations such as comparison or arithmetic operations where the types are not the same we will meet some weird things. Let's figure them out 🔎.

## Basic data types
%[https://codepen.io/atelypham/pen/oNZJRKv]

In this example, we can see how JS converts data type when we perform arithmetic operations. All the process performs in 2 operands, **which** is:

- Note by example: `A + B` is an expression; `A`, `B` are operands, `+` is the operator.

- In JS, the adding operation behaves in two ways, concatenate strings and sum two numbers.

    - So if 2 operands are not a number, JS tries to convert all to the string and concatenate them. Otherwise, JS sum two numbers. `"2" + 3` ⇒ `"2" + "3" ⇒ "23"`.

    - Others operators work differently, JS try to convert all operands to number (type `Number`) then implements the expression. `"2" - 3` ⇒ `2 - 3 === -1`; `"2" * "3"` ⇒ `2 * 3 === 6`.

⚠️ Note:

- `true` and `false` also convert to number `1` and `0`.

- JS converts a string to a number, JS will ignore the beginning and ending white spaces in the string, `+" -9 "` convert to `-9`. (`+" -9 "` is unary plus in JS, it same as `Number(" -9 ")`)

## What about the non-primitive data type like `Array`, `Object`?

%[https://codepen.io/atelypham/pen/bGqzpMw]

The operation in `Array` and `Object` has little difference, JS will try to convert them to the primitive type using `toString` method and `valueOf` method. Then take the result and execute the statement.

> In the example above, `[] + 1` first convert the `[]` to the primitive type using `toString`, then take the result `+ 1`, `[].toString()` is `""` so `"" + 1` is equal to `"1"` 😅.

If you don't believe me, you can override toString method to figure it out, play around with it to make you more understanding.

```javascript
Array.prototype.toString = () => 2222
[] + 1 // => 2223
+[] // Same as Number([]) => 2222
```

What happened here? JS converts the Object and Array in the arithmetic statement and comparison statement, JS uses toString to convert to primitive and execute the statement.

⚠️ Note: When you testing with Object using object literal {}, you should put your Object in the parentheses ({}). Otherwise, JS might execute it as a block of code, like `if(true) {}`, not an Object as you expected.

## `null` and `undefined`

%[https://codepen.io/atelypham/pen/eYvxjYK]

`null` and `undefined` are special cases, where `null`'s value is `0` and `undefined`'s value is `NaN`. You can check by `+null` or `+undefined`. So after convert to numbers, all the process behavior is the same above.

- `1 + null` convert `null` to `0`, then `1 + 0` the result is `1`.

- `1 + undefined` convert `undefined` to `NaN`, then execute the expression `1 + NaN` the result is `NaN`.

The operation converts null and undefined happen first then all the other operations happen after that.

## Exercises

%[https://codepen.io/atelypham/pen/wvJNOYp]

