4. Type Coercion
Tags: javascript, webdev, beginners, programming
Published: 2022-01-15 09:15:40

### **Articles**

- [What you need to know about Javascript's Implicit Coercion — Promise Tochi](https://dev.to/promhize/what-you-need-to-know-about-javascripts-implicit-coercion-e23) 100%
- [JavaScript Type Coercion Explained — Alexey Samoshkin](https://medium.freecodecamp.org/js-type-coercion-explained-27ba3d9a2839) 100%
- [Javascript Coercion Explained — Ben Garrison](https://hackernoon.com/javascript-coercion-explained-545c895213d3) 100%
- [What exactly is Type Coercion in Javascript? - Stack Overflow](https://stackoverflow.com/questions/19915688/what-exactly-is-type-coercion-in-javascript) 100%

---

## Definition
Type coercion is converting a value from one type to another. 
### Categorization
There are only 3 types of conversion in Javascript.

- to string
- to boolean
- to number

Whether type coercion is intentioned by programmer or not, we can divide it into two type. **Explicit type coercion** which is also known as **type casting**, is when programmer intentionally alter the type of value. On the other hand, **implicit type coercion** is when Javascript automatically changes the type of value by given context. 

Additionally, primitve value's type coercion and Object's type coercion works different.

---

## Primitive type value
### to string
#### Explicit
``` javascript
String(123); // '123'
```
`Symbol` type can only be converted to string explicitly. 
#### Implicit
`+` **binary** operator (dont confuse with unary!) which one of operand is string converts non-string value to string type.
``` javascript
123 + 'hi1' // '123hi1'
```
---

### to Boolean
In Boolean, there are only 2 results; true or false.
#### Explicit
``` javascript
Boolean(2); //true
```
#### List of falsy values
``` javascript
Boolean('');
Boolean(NaN);
Boolean(false);
Boolean(0);
Boolean(-0);
Boolean(null);
Boolean(undefined);
```
Except this list, all values are converted to `true`.


#### Implicit
Logical operators(`||`,`&&`,!) implicitly converts to boolean type.
- ! : flip the boolean value and return `true` or `false`
- || : return first true value
``` javascript
console.log(2 || 1); // 2
```
- && : return first falty value, if none return the last value
``` javascript
console.log(0 && ""); // 0
console.log(2 && 1); // 1
```
---
### to Number
#### Explicit
``` javascript
Number('1'); // 1
```
When converting string to number, Javascript engine trims the leading and trailing whitespaces. If trimmed string doesn't represent valid number, it returns NaN. If string is empty, return 0. 

For `null`, it returns 0 and for `undefined`, it returns NaN.
``` javascript
Number('   2'); // 2
Number('   2 3'); // NaN
Number(''); // 0
Number(null); // 0
Number(undefined); // NaN
```
#### Implicit
- comparison operators(`>`, `<`..)

- arithmetic operators(`-`,`+`, ..)
	For `+`, if one of operand is string type, then it converts to string type. `+` converts to numeric value, if both operands aren't string.
- bitwise operators(`|`,`&`..)

- unary `+` operator 

- loose equality operator `==`
	We should be be careful with this operator. There's few exceptions. 
    First, if both operand is string type, it doesn't triggers numeric conversion. 
    Second case is with the `null`. `null` only loosely equals to `null` and `undefined`.
    Third case is with NaN. NaN is not loosely equals to itself.
``` javascript
console.log(null == 0); // false
console.log(null == null); // true
console.log(null == undefined); // true

console.log(NaN == NaN); // false
```
---

## Object type coercion
The logic itself is same. For object, still there are only 3 types of type conversion. 
Algorithm works as follows. 

0. if input is primitve, just return it.

1. Call input.toString() or input.valueOf().
	If operator does numeric conversion, do input.valueOf() first, and then do input.toString(). If operator does string conversion, do input.toString(), and then do input.valueOf(). Keep it mind, it returns `true` for any objects for boolean conversion.

2. If both input.toString() and input.valueOf() doesn't returns primitve value, throw `TypeError`. 

However, most objects(except wrapper object `Number`) doesn't have `valueof` or `valueof` returns `	this` which is not primitve value. So we can just think that both conversion ends up calling `toString`. 
Keep in mind, 
``` javascript
console.log({}.toString()); // "[object Object]"
```
``` javascript 
console.log([1] / 2);
-> console.log('1' / 2);
-> console.log(1 / 2);

console.log('true' + {first: "second"});
-> console.log('true' + '[object Object]');

console.log(!+[0])
-> console.log(!0); // because + is unary operator
-> console.log(true);
```
One thing, `Date` object's default is string converison. It means that
``` javascript
console.log(new Date(0) + 0 );
-> console.log('Thu Jan 01 1970 02:00:00 GMT+0200 (EET)' + 0);
-> console.log('Thu Jan 01 1970 02:00:00 GMT+0200 (EET)0');

```