JavaScript: By Value Versus By Reference
Tags: javascript, beginners
Published: 2019-05-25 18:47:57

__Why is knowing this topic important?__
<br>
- To understand what really happen when we assign values to a variable
- To avoid potential bugs from occuring

*** 
In JavaScript, when we declare a variable and assign values to it, the underlying JavaScript engine will evaluate 
the type of the given value and decide on how to put that value in the memory. There are two ways on how JavaScript put
that value into memory: by value & by reference.

<br />



#### By Value

First we need to know that all primitive type in JavaScript will be copied by value.
Primitive type in JavaScript are: 
1. String
2. Number
3. Boolean
4. null
5. undefined

So what does "by value" mean? 😕 Lets review this example:

```javascript
// Declare a variable and pass a primitive value to it
let favoriteBand = "Underoath"

// Create another variable and pass favoriteBand as the value
let sameButDifferent  = favoriteBand

// Log the result
console.log(favoriteBand) // "Underoath"
console.log(sameButDifferent) // "Underoath"
```
First we declared a variable called __*favoriteBand*__ and passes the string "*Underoath*" as its value which is a primitive type.
When we do this, JavaScript creates a new memory location for this variable's value.
Then, we declared another variable called __*sameButDifferent*__ and passes the variable __*favoriteBand*__ as its value.
When we log both variable, they both returns the string "*Underoath*" as their value.
<br><br>
Its important to note here that even though both variable logs the same outcome, both of them sits in completely different memory location. When we declared the variable __*sameButDifferent*__, the JavaScript engine creates a totally separate memory location for this variable's value to sit on.

Now if we try to change one value from any variable:
```javascript
// Reassign the value for the variable favoriteBand
let favoriteBand = "Saosin"

console.log(favoriteBand) // "Saosin"
console.log(sameButDifferent) // "Underoath"
```
We can see it does not reflect the other because both of them are essentially not the same. So, if we declare a variable and set its value to be number, boolean or any primitive type, this "by value" rule will apply to them.

<br>

#### By Reference
In contrast, all Objects in JavaScript will be copied by reference.

Objects in JavaScript includes:
1. Object (obviously)
2. Array
3. Function


Lets see what "by reference" means. Consider the example below:

```javascript
// Declare a variable and assign an object to it
let firstAlbum = {
    single: 'In Division'
}

// Create another variable and pass firstAlbum as the value
let secondAlbum = firstAlbum

// Log the result
console.log(firstAlbum) // {single: 'In Division'}
console.log(secondAlbum) // {single: 'In Division'}
``` 

Lets go through this code. First we declared a variable called __**firstAlbum**__ and passes an
object to it. The JavaScript engine now will create a new memory location for this object 
to sit on.
Then we declared another variable __**secondAlbum**__ and passes the variable __**firstAlbum**__
as its value. Now JavaScript will see that the value we pass to __**secondAlbum**__ contains an <ins>object</ins> that already exist in the memory.
Instead of creating a new memory location, It will simply point this variable to the same object
created for variable __**firstAlbum**__.

<br>

Now lets change one value of a property inside that object:
```javascript
// reassign a value inside the Object
secondAlbum.single = 'Paperlung'

// log the result
console.log(firstAlbum) // {single: 'Paperlung'}
console.log(secondAlbum) // {single: 'Paperlung'}
``` 
When we log the variables, it shows that the changes is reflected on both variable even if we only make
the change on a single variable. This is because they both are essentially the same object and refer to the same memory location.

<br>

Here's another example:
```javascript
// Pass object as parameters
function changeSingle(obj) {
    obj.single = 'Seven Years';
}

// Call the function
changeSingle(firstAlbum);

// log the result for both variables
console.log(firstAlbum); // {single: 'Seven Years'}
console.log(secondAlbum); // {single: 'Seven Years'}
```
We pass the object as a parameter inside a function, then we change a value of a property inside that object.
That change is reflected on both variables because we are still changing the same object.

<br>

Lastly, lets assign the variable __**firstAlbum**__ with a completely new object:
```javascript
// reassign a new object to the firstAlbum variable
firstAlbum = {
    producer: "Mark Goldman"
}

// log the result for both variables
console.log(firstAlbum); // {producer: 'Mark Goldman'}
console.log(secondAlbum); // {single: 'Seven Years'}
```
Now JavaScript sees that a new object is created so it will assign another memory location specifically for this object. This same rule applies to functions and arrays.

<br>

To simplify, whenever we create a primitive type and pass it around it will always create a new value inside the memory. When we create an object and pass it around, it will always refer to the same memory location if it already exist.