Primitive and Non-primitive
Tags: webdev, javascript, programming, tutorial
Published: 2023-06-08 15:14:24

## Overview

In JavaScript, the data types are divided into two broad categories:

1. [Primitive data types](#primitive-data-types)
2. [Non-primitive data types](#non-primitive-data-types)

Primitive data types such as `string`, `number`, `null`, `undefined`, and `boolean`, are passed by value while non-primitive data types such as `objects`, `arrays`, and `functions` are passed by reference.

| Value Type / Primitive Data Type | Reference Type / Non-primitive Data Type |
| -------------------------------- | ---------------------------------------- |
| String                           | Object                                   |
| Number                           | Array                                    |
| Boolean                          | Function                                 |
| Symbol                           |                                          |
| Undefined                        |                                          |

The main difference between primitives & non-primitives is that primitives are **_immutable_** i.e. there is no way to change a primitive value once it gets created, whereas non-primitives are **_mutable_** i.e. the value of an object can be changed after it gets created.

## Primitive data types

```js
let name = "Rizwan";
console.log(name); // Rizwan

name[0] = "r";
console.log(name); // Rizwan
```

In the above example, I've created a string variable named `name` and assigned the value 'Rizwan' to it. Then, I've tried to change the first character of the string to 'r' using the bracket notation `[0]`. But, the value of the variable name remains the same. This is because the string is a primitive data type, and it is **_immutable_**.

Now let's see another example:

```js
let name = "Rizwan";
console.log(name); // Rizwan

name = "rizwan ashiq";
console.log(name); // rizwan ashiq
```

Here, first, I assigned 'Rizwan' to `name` then I console logged it, and we got `Rizwan` in the console, then I reassign the value 'rizwan' to `name` and on console logging it, we got `rizwan` in the console. Now you may ask how it can happen as I already mentioned that primitive data types are **_immutable_**, and string is one of them?

To understand this, we need to break down the above example into two steps:

1. First, I created a variable named `name` and assigned the value 'Rizwan' to it.
2. As result of the above step, a memory location is created, and the value 'Rizwan' is stored in it.
3. Then, I reassign the value 'rizwan ashiq' to `name`.
4. Eventually, a new memory location is created, and the value 'rizwan ashiq' is stored in it
5. And the variable `name` is updated to point to the new memory location. So, `name` is pointing to the new memory location where the value 'rizwan ashiq' is stored.
6. Now, the previous memory location where the value 'Rizwan' was stored is available for garbage collection, and it will be removed from the memory once the garbage collector finds it.

Hence, we come to the conclusion that the value which was created previously is not modified, it is sent for garbage collection while the variable `name` now points to the newly created memory space, which has 'rizwan ashiq' stored in it. In simple words, we are just making the variable point to a different space in the memory and not modifying its existing value.

### Comparison of primitive data types

Primitive data types are compared by value. If two values are the same, then they are strictly equal.

```js
const num1 = 40;
const num2 = 40;
numb1 === num2; // true

const string1 = "Mercury is the closest planet to the sun";
const string2 = "Mercury is the closest planet to the sun";
string1 === string2; // true
```

## Non-primitive data types

```js
const person = {
	name: "Rizwan",
	age: 25,
};

console.log(person); // { name: 'Rizwan', age: 25 }

person.name = "rizwan";
console.log(person); // { name: 'rizwan', age: 25 }
```

In the above example, we have created an object named `person` and assigned the value `{ name: 'Rizwan', age: 25 }` to it. Then, we have tried to change the value of the `name` property to 'rizwan' using the dot notation. And, we got the updated value in the console. This is because the object is a non-primitive data type, and it is **_mutable_**.

### Comparison of non-primitive data types

Objects and arrays are not compared by value. That means even if two objects and arrays have the same values and properties or the same elements, respectively, they are not strictly equal.

```js
const person1 = {
	name: "Rizwan",
	age: 25,
};

const person2 = {
	name: "Rizwan",
	age: 25,
};

person1 === person2; // false

const persons = ["Rizwan", "Ashiq"];
const persons2 = ["Rizwan", "Ashiq"];

persons === persons2; // false
```

Two objects are strictly equal only if they refer to the same object, i.e. they are pointing to the same memory location.

```js
const person1 = {
	name: "Rizwan",
	age: 25,
};

const person2 = person1;

person1 === person2; // true
```

In the above example, we have created two variables named `person1` and `person2` and assigned the value `{ name: 'Rizwan', age: 25 }` to both of them. Then, we have compared both the variables using the strict equality operator. We got `true` in the console. This is because both the variables are pointing to the same object in the memory.

## Where do primitive and non primitiWave value stores:

Note: In JavaScript, primitive values are stored in the stack, and non-primitive values are stored in the heap.

What is Stack and Heap?

Stack is small (in size) and fast in access, while heap is large (in size) and slow in access. So, when we create a primitive value, it is stored in the stack, and when we create a non-primitive value, it is stored in the heap. The stack stores the reference to the heap.

When we assign a primitive value to a variable, a copy of the value is stored in the variable. But, when we assign a non-primitive value to a variable, a reference to the value is stored in the variable. So, when we change the value of a non-primitive variable, the reference remains the same, but the value is changed in the heap.

Now the question is the question is why we need to store the reference to the value in the stack instead of storing the value itself in the stack?

The answer is that the stack is small in size and fast in access, while the heap is large in size and slow in access. So, when we store the reference to the value in the stack, it is fast in access, and when we need to access the value, we can access it from the heap.

## Conclusion

- In JavaScript, we have value types, also called primitives, and reference types (non-primitives) which are objects.
- Primitives are `number`, `string`, `boolean`, `symbol`, `undefined`, and `null`, whereas, Non-primitives are `objects`, `functions`, and `arrays`.
- In pass-by value in JavaScript, a copy of the original variable is created, so any changes made to the copied variable do not affect the original variable.
- In pass-by reference in JavaScript, we pass the reference of the actual parameter. No copy is created in the memory.