A quick dive 🏊 into the data types in JavaScript to understand them from behind the scenes 📽️.
Tags: javascript, tutorial, webdev
Published: 2021-01-26 01:00:13

In Javascript there are 2 categories of data types:
####**1- Primitive data types:** 
All primitives are **immutable** (unchangeable) 🛌, there are 7 primitive data types:
- `Number`: for numbers of any kind: integer or float.
- `String`: may have zero or more characters.
- `Boolean`: has only two values (true and false).
- `Null`:  for unknown values – a standalone type that has a single value `null`.
- `Undefined`:  for unassigned values – a standalone type that has a single value `undefined`.
- `Symbol`: for unique identifiers.
- `BigInt`: is for integer numbers of arbitrary length.

####**2- Non-Primitive data type:**
Non-primitive is **mutable** (changeable) 🦎, there is only one non-primitive data type:
- `Object`: for more complex data structures.

Arrays and functions in JavaScript belong to the `object` data type.

---
####**Let's dive deeper into these data types**
Look at this code, I will use a string (primitive) and an array (non-primitive). 
```javascript
var str = 'Berlin'
var arr = [1,2,3]
```
You can access the value inside them by the same way
```javascript
console.log(str[0]) // 'B'
console.log(arr[0]) // 1
```
You can change array's item, like this..
```javascript
arr[0] = 5
console.log(arr[0]) // 5
```
What about a string? can we do the same and change any char in this string?
```javascript
str[0] = 'G'
console.log(str) // ??
```
So here is the point, you can't do that with string 🙅‍♂️.
Because a string is a primitive data type. And you can't change any primitive value.
```javascript
str[0] = 'G'
console.log(str) // 'Berlin'
```
---
####**What about this case?**
```javascript
var city = 'Berlin'
city = 'Frankfurt'
console.log(city) // ??
```
The variable may be reassigned a new value, but the existing value can't be changed in the ways that objects, arrays, and functions. Immutability here doesn't make any effect, look how this happens..

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/n6ps6hz90cmd6oiqwqoa.png)

Here we assign a brand new value 'Frankfurt', so there is no problem.

---
####**What about this case?**
```javascript
function square(x){
  x = x * x
}
var num = 10
square(num)
console.log(num) // ??
```
In this case, `square()` will only ask, what the value of variable `num`? then it receives this value as argument.
So `square()` will not effect the value of `num`.
```javascript
console.log(num) // 10
```
---
####**Now we are in objects phase, let's explore it.. 🔭**
```javascript
var num1 = 5, num2 = 5, obj1 = {}, obj2 = {};
console.log(num1 === num2) // ?
console.log(obj1 === obj2) // ?
```
In primitive data types, if we have 2 variables with the same value, so they both will pointing to this value, like this..

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5nlwbmsfgrbuq02y9ulf.png)

But with objects (non-primitive) it's different, every time we assign object {} to a variable, Javascript will create a brand new object value. The same goes for array, dates, functions and other objects, look how..

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mh70zewvuv1bqpowazms.png)

The image above explain us this answers.
```javascript
console.log(num1 === num2) // true
console.log(obj1 === obj2) // false
```

---
####**Let's dive deeper in objects to see how they are mutable!**
```javascript
var car1 = {
  model:'G 63',
  brand: {
    name: 'Mercedes'
  }
}

var car2 = {
  model:'GT 63 S',
  brand: car1.brand
}

car2.model = 'GT Coupe'
car2.brand.name= 'Audi'

console.log(car1.model); // ?
console.log(car1.brand.name); // ?
console.log(car2.model); // ?
console.log(car2.brand.name); // ?
```
Let's break this problem down to figure out the answers..
1- First object's draw:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9m650mieyzae07w38cuk.png)

2- Second object's draw:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1wvhbs71w9a7verp7v9j.png)

3- Then 2 changes:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0z8bz7m8lisa110qkzat.png)

As you saw, we can change the properties value within the object, this is called 'Mutation'. 

```javascript
console.log(car1.model); // "G 63"
console.log(car1.brand.name); // "Audi"
console.log(car2.model); // "GT Coupe"
console.log(car2.brand.name); // "Audi"
```
---
####**Well done, diver, you are in an interesting area. Go on.. 👏**
```javascript
var city = {
  name:'München',
}

var _location = {
  state:'Bavaria',
}

console.log(_location.name); // ?
```
Yes, as you said the answer is `undefined`, but how do we access property `name` from object `location`?
First off, let's see how the console prints the object.
```javascript
var _location = {
  state:'Bavaria',
}
console.log(_location);
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/97a5g29tfa7wk515342s.PNG)

Each object in Javascript by default contains a property called `__proto__`, so we will use this property to achieve our goal, as follows..
```javascript
var _location = {
  __proto__: city,
  state:'Bavaria',
}
```
Now we will draw our visual explanation after this modification:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/y4b980xa928e7hjrnmdd.png)

Based on this case, we can access `name` from `location` object, but we can't access `state` from `city` object.
```javascript
console.log(_location.name); // 'München'
console.log(city.state); // undefined
```
Look at this example and try to get the answer.
```javascript
var city = {
  name:'München',
}

var _location = {
  __proto__: city,
  name:'Bavaria',
}
console.log(city.name); // ?
console.log(_location.name); // ?
```
The `location` object will look for a `name` property in the ` city` object, only when it does not contain the required property `name`.
In this example, the `location` object has its own property `name`, so the `city` object will not be seen.
```javascript
console.log(city.name); // 'München'
console.log(_location.name); // 'Bavaria'
```

---
####**Last interesting point about using `__proto__`**
```javascript
var humans = {}
var animals = {}
var plants = {}

humans.__proto__.need= 'Water'

console.log(humans.need); // 'Water'
console.log(animals.need); // 'Water' 
console.log(plants.need); // 'Water' 
```
As you saw if we add property `need` to `__proto__` we can access the value of this property `need` from any other object.

---

This is where our diving trip ends 📍 I hope you have enjoyed and found it a useful trip. Wait for me on other exciting diving trips ✨.

---
####**Resources:**
- [just javascript](https://justjavascript.com/) a great email list (highly recommend course), explaining the basic principles of Javascript using mental models (illustrations in the article 👆) to explain how they work behind the scenes.
- [MDN web docs](https://developer.mozilla.org/en-US/).
- [Javascript info](https://javascript.info/).
- All illustrations were made using [excalidraw](https://excalidraw.com/).