Understanding JavaScript Primitive vrs Reference Values
Tags: javascript, webdev, beginners, programming
Published: 2022-01-06 21:45:23

Hello World, all programming languages have built-in data types. In JavaScript, there are seven well-known data types.
These `data` types can be grouped into `primitive` and `reference` values.
In this post, we will learn the difference between `primitive` and `reference` values in JavaScript. 

## Understanding the data types 

> In computer programming, a data type tells the compiler or interpreter what type of value a variable has.  

There are seven data types in the JavaScript programming language. 
* `undefined` 
* `null`
* `string`
* `numbers`
* `symbol`
* `boolean`
* `object`

These data types can be grouped into `primitive` and `reference` values ( a value can be seen as some kind of data which will be stored in a varaible ).

### Primitive data types
There are six primitive data types 

* `undefined`
* `null`
* `string`
* `numbers` 
* `symbol`
* `boolean`

### Non Primitive data type
`Object` are considered `reference` or `non-primitive` values. Keep in mind that `arrays` and `functions`  are classified as `Objects`

## Storing the data types or values 
The JavaScript engine has two places where it store data  or values, they are the  `stack` and `heap`.

Primitive data types do not have complex values, their values are fixed hence stored in the `stack`.

However, the size of a `reference` value is dynamic or complex. For instance, 

- An `Object` can have new properties added to it.
- An `array` can have elements added or removed from it.
- A function can have so many lines of code and more statements being added.
Due to all these complexities,  we store `reference` values in the `heap`.

 
## Assinging  values
When you assign a `value` to a `variable`, the JavaScript engine will determine whether the value is a `primitive` or `reference` value.
This will help determine where to store the variable, either in the `stack` or `heap`.
 
### Accessing a primitive value 

When you declare a **variable** and assign a `primitive` value to the variable, example `let a = 40`.  The JavaScript engine 

- Will allocate some memory or space in the `stack`
- Give it a **unique identifier** which is an address or location to help locate the value when the need be
- Initialize the variable and assign the value.

Let's see an example 

```
var x = 10;
```
In the above code:

- The JavaScript engine will create a **unique identifer** (Eg. **A001**) in the browser's memory, and the assignment operator `=` will now assign or store the value `10` in that specific place we allocated for it (i.e A001). 

- Because the value, `10` is a primitive value, when you **access **the `variable`, you will use  or manipulate the **actual value** stored in that variable.

- This means, the variable that stores a primitive value is **accessed by value**


### Copying primitive values
Let's see what happens when you decide to **assign a variable that stores a primitive value to another variable**. 

> When you assign any variable that contains a primitive value to a new variable, the value stored in the initial variable is created and copied to the new variable. 

Let's take a look at the example below 

```
let a = 40;
let b = a; //assign value stored in`a` to `b`.
```

- First we declare a variable `a` and store a value of `40`.
- Next, we declare another variable `b` and copy the value stored in `a` to it. 
Let's check the output of both variables 

```
console.log(`a =${a} and b = ${b}`)

```
The output will be 

```
a =40 and b = 40
```
Anytime a variable is declared, we allocated a location in memory and store the value there.  

- In the above, with `let a = 40`,  we allocated a **location **in memory lets call that allocated location **Ax001**. Meaning when we go the **Ax001**, we can have access to the value `40`.

- When we declare `b` variable, we are also creating a **location in the memory** so we store a value. Let's call this location **Bx001**

- **Ax001** and **Bx001** will be the location for two places in-memory where we are storing values.

- Now, we copied the value stored in `a` to `b` 

```
let a = 40;
let b = a; //copies value stored in `a` to `b`
```

- Internally, JavaScript engine will copy the value stored in `a` into the **location of b** (ie. **Bx001**). Meaning at location **Bx001** we now store  the value `40`.

#### Changing the initial value
We then decide to change the value we stored in the variable `a`, would the value stored in variable `b` change too ?

```
a = 50; //change value stored in a
console.log(`a =${a} and b=${b})
```
The output will be 

```
a =50 and b =40
```
**Changing the value stored in `a` does not change the value stored in `b`. Eventhough , the value of `a` has been assigned to `b`**  Why ?

This is what is happening

- The `values` of variables `a` and `b` are stored in different location in memory. 

- The value `40` is stored in the location **Ax001** of the variable `a` whilst what ever **value **is stored in variable `b` will be kept in the location **Bx001**.

- Eventhough we later assign the value stored in `a` to `b`, they have been stored in **two separate locations**. 
- So if you change the value of variable `a`, it will not change the value stored in variable `b`. 

- Variables **a **and **b ** have **no relationship,**(due it their different locations in-memory). 

#### In Summary
In summary for primitive values, when you change the value stored in the `a` variable, the value of the `b` variable doesn’t change.Because `a` and `b` are different locations in memory.

### Accessing an non-primitive value 

We have mentioned that non-primitive values are stored in the `heap` this is because non-primitive values have complex data structure so need some huge memory to store it. 

When we define a variable and assign a non-primitive data type to it. This is what happens:

- The JS engine creates a **unique identifier** or **address **eg(NPx001), allocate some memory or space in the `heap` and store the **actual value** at that **address** 

- Now if the script starts executing and it comes across a `non primitive` value eg. 

```
user = {
firstName: "Emmanuel",
lastName: "Kumah"
}
```

- What the `user` variable is storing is a pointer, **pointing to the **address **where the value is stored** and not the actual value.
- It is not the **data value itself**, but it _tells the variable where to look to find the value_.

> If you looked at the in-memory value of a reference type, you’d see a memory address (or a “reference” to a spot in memory). 

- Because the **actual value is stored in the heap** and we need access to it, we will create a **reference ** or some form of pointer on the variable, eg. `user` and forward ** the location to the value stored in the heap to the `user` variable** 

- Now in the call `stack` what we have access to, is **the **reference ** or pointer to the **actual value** in the `heap`**

- Meanning, when you want to use an object or any **non-primitive data type**, you work on the **reference of that object**,rather than the actual object.

> When we access a reference value, we manipulate it through reference, not through its actual value that is stored. Thus, variables that are reference values are accessed by reference

### Copying reference value
When we assign a variable that stores a reference value to another variable, the **value stored in the initial variable is also copied into the location of the new variable**. 

```
let user = {
  firstName: "emmanuel",
  location: "Ghana"
}
let admin = user; //assign variable to new variable

console.log(`admin is ${admin.firstName} and user is ${user.firstName}`);
```
The output will be 

```
admin is emmanuel and user is emmanuel
```
The difference is, the values stored in both variables will **be the address of the actual object stored on the heap. **

#### Changing the values
 **Both variables** are referencing the **same object**. Meaning, we can manipulate the **original object** from **both variables**

Let's try and change the `firstName` property of the `user` object and see what will happen to properties in `admin` object.

See the code below

```
let user = {
  firstName: "emmanuel",
  location: "Ghana"
}
let admin = user; // assign user to admin

console.log(`admin is ${admin.firstName} and user is ${user.firstName}`);

admin.firstName = "Stephen"; //change the firstName property 

console.log(`admin is ${admin.firstName} and user is ${user.firstName}`);

```
 The output will be

```
admin is emmanuel and user is emmanuel
admin is Stephen and user is Stephen
```
From the above, when we change the value stored in the `user` object, it also changed the value stored in the `admin` object. 

We can therefore **manipulate the orginal object from both variables**, and changing one property in one variable, will change the property in the other variable.

## In summary 
In this post, we learnt that a varaible can chold one of two value types: `primitive` values or `reference` values. 

- Primitive values are data that are stored on the stack. 

- Primitive value is stored directly in the location that the variable acesses. 

- Reference values are objects that are stored in the heap

- Reference value stored in the variable location is a pointer to a location in memory where the object is stored. 


If you found value in this post, kindly share it to your social networks. It will be of value to someone else. Would love to read your comment on this post too. 

Written with love from Ghana , me daa se (thank you )