JavaScript References
Tags: javascript
Published: 2021-10-28 19:36:42

A few years back when I was studying Electronic Engineering, one of the requisites was Programming I, II, and III. **C++** was the first programming language I learned, and I must say it was the reason I chose my current career (I realized I hated dealing with hardware). One of my professors was an old lady that used to teach in the classroom writing code on the board, instead of using a computer. Although I thought it was a waste of time, writing things down several times helped me understand the core concepts. 

I remember a class when she explained **references**, and how every piece of data has a place in memory. At first, it was quite difficult to understand, but finally, she used the word "**pointer**". Ok, I know what a pointer is and I can picture it (kind of like an arrow, I will say), now what? Well, let's say we have a variable *named* `myFavCar` that stores a *value* of `"Ferrari"`. This piece of data is stored in someplace in the computer's memory, and it can be accessed by using its name, which is **pointing** to that place in memory. So, whenever we want to display the value of a variable, the function `console.log` uses the variable name as an argument and gets the data from where is stored.

```javascript
let myFavCar = "Ferrari"
console.log(myFavCar); // prints "Ferrari"
```

## Primitives vs. Objects

If we want to reassign that value to "Lamborghini" instead, we should start talking about *immutability*, and how primitives (`String`, `Number`, `Boolean`, `Null`, and `Undefined`) and **immutable** and how `Objects` (pretty much everything else in JS) *can* be modified. Since we are using a `String` variable, is not like Lamborghini will override ~~Ferrari~~. We can't modify a `String`, so what is going to happen is that myFavCar now will be pointing to **another** place in memory where this new value is stored. 

```javascript
let myFavCar = "Ferrari"
myFavCar = "Lamborghini";
console.log(myFavCar); // prints "Lamborghini"
```

This makes a lot of sense when I think about String methods returning a new String instead of modifying the current String value. That's why if we want to keep that new value, we have to store it in a new variable (*aka*, pointer to a new place in memory).
```javascript
let text1 = "Hi";
let text2 = "there";
let text3 = text1.concat(" ", text2);
console.log(text3); // prints "Hi there"

// this does not modify text1 or text2 values
```
### How does mutation work?

A **mutation** is something that we want to avoid at all costs, and that means making sure none of our functions change their arguments or anything outside of them. This kind of function is called **pure function** (I learned that today!). Whenever we pass an object as an argument for a function, that function can modify the object that's outside of the scope. A way to avoid this kind of mutation is to use the spread operator (`...`) and save a copy of the object and modify and return that copy.

```javascript
let customer = {
   name: "John Doe",
   dob: "2/13/1987",
   address: "123 Park Ave",
   subscriptionAct: true,
}

function updateInfo(customer) {
   // create a variable that stores a copy of the object
   // this will be a NEW object
   let customerUpdated = { ...customer }

   // modifies the copy
   customerUpdated.subscriptionAct = false;
   return customerUpdated;
}

// the function will return a new object
// we save it in a variable
customer = updateInfo(customer);
```

Without the spread operator, `customerUpdated` will point to the customer object. So pretty much we will have customer and customerUpdated pointing at the **same** object. This is called *copy by reference*, and it means that if we modify either one, it will affect both of them. 

*Copy by value* can be done with primitives, since they can't be modified, they just create a new place in memory to store that new value (even if it's a copy).
```javascript
let a = "a";
let b = "b";
a = b;
b = "hello";

console.log(b); // prints "hello"
console.log(a); // prints "b"
```
In this case, `a` copies the value that's stored in `b`, which in this case is a String. After reassigning `b` a new value, we can notice that `a` didn't change. That's because it copied just the value, but does not reference that address where `b` is pointing at.

Understanding these concepts was difficult and very confusing at the beginning, but after a few years of programming in different languages, I was able to understand, being a crucial part of data structures and algorithms. I used this [article](https://daveceddia.com/javascript-references/) as a reference for writing this post, which helped me understand these concepts even more.