Back to JS Basics - Types & Coercion
Tags: javascript, beginners, webdev
Published: 2020-10-04 21:06:17

*These are my notes as I go back & revisit the nitty gritties of JS core concepts.*

## JavaScript Data Types
A value in JavaScript is always of a certain type (ex:number) - data type is the attribute which determines the behavior of a particular value and how it is treated (ex: 1 vs "1"). This also effects how different operators work with the value.

JavaScript is a dynamic language or loosely typed therefore **a variable doesn’t associate with any type - its value does**. That means the same variable may be reassigned a new value of a different type.

```jsx
var x = 5; //x is a number
x = "Hello world" //x is now a string
```

<br\>
There are basically 9 types of data types in JS with 

- **6 primitives:** number, string, boolean, undefined, bigInt, symbol. A primitive data value is a single simple data value with no additional properties and methods.
- **2 structural**: objects and functions. Object is a collection of properties, and a property is an association between a name (or key) and a value. A property's value can be a function, in which case the property is known as a method. **Arrays, regular expressions, date, etc. are all different types of objects.**
    
    Functions are like a sub-type of objects.
- 1 special kind of primitive: null. `null` is a special instance of primitive datatype which points **intentionally** to a nonexistent or invalid object or address.

Both `null` and `undefined` cannot hold any value.

**This article covers primitive types** (& parts of `null`)


### Null vs Undefined

 `undefined` means a variable has been **declared but has not yet been assigned a value. (***An **undeclared** var, by contrast, is one that hasn't been declared yet, and will return a reference error***).**

`null` represents null, empty, or non-existent reference. It is a blank object reference.

### Peculiarities of `Number`

- Number ≠ Integer ( 1, 1.0, 1. are all valid 'number' in JS. That may be important when trying to invoke a number method)
    
    ```jsx  
          
       console.log(1.toPrecision( 6)) // Uncaught SyntaxError
       console.log(1..toPrecision( 6)) //4.00000
    
    ```
    
    Ideally, its better to assign value to variable and then access function on the var.
- Floating point arithmetic is not always 100% accurate
    ```jsx  
          
       console.log(0.1 + 0.2) //0.30000000000000004
    
    ```
- **NaN**(not a number) : Any mathematical operation in which both operands aren't numbers (or values that cannot be forced into number) results in an invalid number, giving the NaN value.
    ```jsx  
          
       console.log(5 - '123' ) // -118
       console.log(5 - '12 3' ) // NAN
    
    ```   
    NaN is a very special value in that it's never equal to another NaN value.

     ```jsx  
          
       console.log(NaN == NaN) //false
    
    ```

## Type Conversions & Coercions

JS variables can be can be converted to a different data type by:

1. Use of a JavaScript function - we explicity convert to a different type. (Ex: `String(123)`)
2. Automatic or implicit conversion of values - JS coerces an incorrect type to the expected data type. (Ex: `2*"2"`)

There are 3 possible conversions:

- To String
- To Number
- To Boolean

#### 1. To String

`String()` or `toString()` function can be used to explicitly convert to string. All primitives are converted to string type as may be expected:

```jsx
String(123) → '123'
String(true) → 'true'
String(null) → 'null'
String(undefined) → 'undefined'
```
Implicit coercion is triggered by the binary + operator, when (atleast) one operand is a string

```jsx
'a'+2 //a2
```

Note: String concatenation with + is not commutative. Ex: `'$' + 4 + 5` will give '$45' but `4 + 5 + '$'` will give '9$'

#### 2. To Number

- Mathematical operations results in implicit conversion to Number (except in case of + where it can result in conversion to string). It **may not be a valid number** - again NaN is also a sub-type of number!

    ```jsx
       typeof(5 + true); //number
       typeof("6a"*"2"); //number
       typeof(5 - '12'); //number
    ```

    An empty string , empty array, becomes 0. `true` is 1, while `false` is 0.

- In explicit conversions of strings, white-spaces from the start and end are removed.

```jsx
Number(' 123 ') // 123
Number('12 3') // NaN
```

- When (loosely) comparing values  of different types, there is implicit conversion to numbers. We will visit comparisons shortly.

#### 3. To Boolean

- Values that are intuitively “empty”, like 0, an empty string, null, undefined, and [] (**not {}**), become false.
Everything else is true - **including "0"** 
- `If` statements: Logical operators (|| and &&) **do not return boolean values**.
    
    ```jsx
    
       a||0; [//a](//a) 
    
    ```
    
    When used within the condition of an `if` statement, there is an implicit coercion to boolean type.

### Comparisons (Loose '==' vs Strict '===' equality)

As mentioned earlier, `==` uses type coercion to numbers if required.

A strict equality operator `===` checks the equality without type conversion. If two values are of different types, then `a === b` immediately returns false without an attempt to convert them.

```jsx
console.log('0' == 0) //true
console.log('0' == false); //true
console.log('0' === false); //false
```

`Number(null)` & `Number(undefined)` are 0 & NaN respectively - so, they aren't equal.

```jsx
null==undefined // false
```
<br\>
Sources:

[You-Dont-Know-JS/types & grammar](https://github.com/getify/You-Dont-Know-JS/tree/1st-ed/types%20%26%20grammar)

[MDN: JavaScript data types and data structures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures)

[https://javascript.info/](https://javascript.info/)