JavaScript — Primitive Values Vs Reference Values (Ways to fix Object Mutability)
Tags: javascript, react, beginners
Published: 2019-09-21 16:09:14

This is going to be a long post but trust me it’s worth a read.

JavaScript is dynamically typed language which means types are not defined at compile time like other object-oriented languages. JavaScript provides two categories under which the data types are divided.

1.	Primitive Values
2.	Reference Values

#Primitive Values:#
 
>In JavaScript, a primitive is data that is not an object and has no methods. There are 7 primitive data types: string, number, boolean, null, undefined, symbol, biginit. 

Most of the time, a primitive value is represented directly at the lowest level of the language implementation.

All primitives are immutable, i.e., they cannot be altered. It is important not to confuse a primitive itself with a variable assigned a primitive value. The variable may be reassigned a new value, but the existing value cannot be changed in the ways that objects, arrays, and functions can be altered.” - [Source - MDN](https://developer.mozilla.org/en-US/docs/Glossary/Primitive)

To break the above definition, it simply means that in case of primitive values, it creates and assigns a fixed location in memory for the defined variable. The primitive values are stored on [Stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) and the name itself is intuitive enough to understand that it is a stack of data, which has **LIFO** i.e. last in first operation.

```
// Primitive Values..

let testString = 'Hello World';
let testString1 = testString;
console.log('testString:', testString); // Hello World 
console.log('testNumber:', testString1 ); // Hello World

testString1  = 123;

console.log('testString:', testString); // Hello World
console.log('testNumber:', testString1 ); // 123
```
As we can see in the above code snippet, it copies and pastes and assigns a new location on stack.

![Stack Representation](https://thepracticaldev.s3.amazonaws.com/i/fky42ddyy446sa4tdcib.png)

#Reference Values:#

Reference values are objects stored in heap.[Heap](https://en.wikipedia.org/wiki/Heap_(data_structure))is a different kind of memory unlike [Stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)).Heap takes little longer to access and is able to hold bigger amount of data where data changes dynamically. The heap is the memory where the elements are not stored on top each other as it is done in stack but randomly, therefore each element has its own address. Reference values are primarily Objects and Arrays (Which are type of objects). To maintain Arrays and Objects in JavaScript we use both stack and heap together. 
Below code snippet shows the object mutability.

```
// Reference Values ..

let testObject = {
    name : 'Chandler',
    age: 28,
    address: 'New York'
};

let testObject1 = testObject;

console.log('testObject:', testObject.name);    // Chandler
console.log('testObject1:', testObject1.name);  // Chandler

testObject1.name = 'Janice';

console.log('testObject:', testObject.name);    // Janice
console.log('testObject1:', testObject1.name); // Janice
```
![what gif](https://media.giphy.com/media/10JLZFAZ7AomjK/giphy.gif)

Here, we see both objects contain same values associated with properties, this happens because objects are handled in a special way i.e. the memory block on stack holds memory address (pointer) of this object which is in turn stored in heap.

![Heap Representation](https://thepracticaldev.s3.amazonaws.com/i/cexq4xbs2uvj6h6baka6.png)

As we see in the above representation when an object is created by assignment, it does not allocate new memory block but creates a new pointer block and pushes onto the stack and both the pointers are pointing to the same place in the memory, resulting a change for variables pointing to elements place in memory.

Let’s see how arrays behave when altered.

```
// lets us check what if we push on Array
let testObject = {
    name : 'Chandler',
    age: 28,
    address: 'New York',
    friends: ['Monica', 'Ross', 'Joey']
};
let testObject1 = testObject;


testObject1.friends.push('Racheal');

console.log('testObject:', testObject.friends);  
 // ['Monica', 'Ross', 'Joey', 'Racheal']
console.log('testObject1:', testObject1.friends); 
// ['Monica', 'Ross', 'Joey', 'Racheal']
```
![Fix that gif](https://media.giphy.com/media/PrEUkNFD9pN2o/giphy.gif)

We can achieve immutability in multiple ways

- ES5 Object.assign :

 This method is used to copy the values of all enumerable own properties 
 from one or more source objects to a target object.
 ```
 const testObject2 = Object.assign({}, testObject);
 testObject2.name = 'Paul';
 console.log(testObject.name); // Janice
 console.log(testObject2.name); // Paul
 ```
- ES5 Array slice():

 The slice() method returns a shallow copy of a portion of an array into 
 a new array object selected from begin to end (end not included) where 
 begin and end represent the index of items in that array. The original 
 array will not be modified.
 ```
 const testObject2 = Object.assign({}, testObject);
 testObject2.friends = testObject.friends.slice();
 testObject2.friends.push('George');
 console.log(testObject.friends); 
 // [ 'Monica', 'Ross', 'Joey', 'Racheal' ]
 console.log(testObject2.friends); 
 // [ 'Monica', 'Ross', 'Joey', 'Racheal', 'George' ]
```
- ES6 [ spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax)Operator:

 This method copies own enumerable properties from a provided object into 
 a new object.
 ```
 // ES6 spread operator for Objects.
 let testObject = {
     name : 'Chandler',
     age: 28,
     address: 'New York'
 };
 const testObject2 = {...testObject};
 testObject2.name = 'Paul';
 console.log('testObject:', testObject.name);    // Janice
 console.log('testObject1:', testObject2.name); // Paul

 // ES6 operator for Arrays.
 const testObject2 = {...testObject};
 testObject2.friends = [...testObject.friends];
 testObject2.friends.push('George');
 console.log(testObject.friends);
 //[ 'Monica', 'Ross', 'Joey', 'Racheal' ]
 console.log(testObject2.friends);
 //[ 'Monica', 'Ross', 'Joey', 'Racheal', 'George'] 
```
- Using[Loadash](https://lodash.com/):

 _.clone(value) – 

 This method creates a shallow copy of the provided value.

 _.cloneDeep(value) – 

 This method is similar to clone except that it recursively clones the 
 value.

> Note : By default all the methods except for _.cloneDeep create shallow copy of the data.

I hope with this article, I was able to differentiate between Primitive and Reference values.
If you find this article helpful and enjoyed it, feel free to share it with friends and colleagues.
Do you have any questions, suggestions or would like to reach to me? Drop me a message on [linkedIn](https://www.linkedin.com/in/muneer-zargar-fe-dev/)