Navigating Mutability and Reference Issues in JavaScript
Tags: javascript, beginners, webdev, programming
Published: 2023-02-27 09:30:50

### Mutability

Mutability refers to the ability of a value or data structure to be changed after it has been created.

### Primitive values are immutable

Primitive values (`string`, `number`, `bigint`, `boolean`, `undefined`, `symbol` and `null`) are immutable, which means that they cannot be changed once created.
    
```javascript
let myString = "Hello, world!"

// Attempting to mutate (change) the string:
myString[0] = "J"
// -> 'J'

// Proof that strings are immutable, because it didn't change:
myString
// -> 'Hello, world!'
```
    
The string `"Hello, world!"` will always be `"Hello, world!"`.
    
We can change the value to which the variable is grasping (a new string that also will be immutable), but the string itself (the value) will remain the same (immutable):
    
```javascript
let myString = "Hello, world!"

myString
// -> 'Hello, world!'

myString = "Hey, world!" 

myString
// -> 'Hey, world!'

myString[0] = "X"
// -> 'X'

myString
// -> 'Hey, world!'
```

### Objects are mutable    

Objects are mutable, as they can be modified:
    
```javascript
// Object creation
const person = {
  name: 'Sarah',
  age: 30
};

// Change the value of a property
person.age = 42;

// Add a new property
person.gender = 'Female';

// Delete a property
delete person.age;

person;
// -> {
//     "name": "Sarah",
//     "gender": "Female"
// }
```
    
In this scenario, an object is mutable because we can change its properties.
    
If the object properties are other objects, their values will be mutable, whereas if they are primitive values, their values will be immutable.
    
```javascript
person.gender[0] = "X"

person
// -> {
//     "name": "Sarah",
//     "gender": "Female"
// }
```
    
Even though an object is mutable, its properties might not be.
    
We can make an object immutable by using the `Object.freeze()` function:
    
```javascript
// Object creation
const person = {
  name: 'Sarah',
  age: 30
};

Object.freeze(person)

person.name = "Connor"
person.enemy = "T-1000"

person
// -> {
// {
//     "name": "Sarah",
//     "age": 30
// }
```   

### The reference confusion in objects

When we assign a **primitive** value to a variable, we are making that variable point to a primitive value in the memory of the machine. We can then assign the variable to another variable, thus making the second variable grasp the first one, and, by extension, **reference** the same value.

If we wanted to change the value of the second variable, ss we cannot change primitive values (they are immutable), we could assign a new value. By doing so, the second variable will be **referencing** a new value.

```javascript
let variable1 = "hello"

let variable2 = variable1

variable2 === variable1
// -> true

variable2 = "bye"

variable2 === variable1
// -> false

variable1
// -> 'hello'

variable2
// -> 'bye'
```

With objects, the behaviour is a bit different. We can assign an object to a variable, which means that the variable grasps the object, or has a **reference** to it. If we then assign that variable to another variable, the new variable will grasp the first one and, by extension, **reference** the same object. As objects are mutable, a change in the object will affect both variables.

```javascript
const object1 = {
    value1: "abc",
    value2: 123
}

const object2 = object1

object2 === object1
// -> true

object2.value1 = "xyz"

object1
// -> {
//     "value1": "xyz",
//     "value2": 123
// }

object2
// -> {
//     "value1": "xyz",
//     "value2": 123
// }
```

On the other hand, we can define a new object in the second variable, and thus make it not reference the same object as the first one. One thing to note is that, even if all the object properties are the same, these two objects will be different:

```javascript
const object1 = {
    value1: "abc",
    value2: 123
}

const object2 = {
    value1: "abc",
    value2: 123
}

object2 === object1
// -> false

object2.value1 = "xyz"

object1
// -> {
//     "value1": "abc",
//     "value2": 123
// }

object2
// -> {
//     "value1": "xyz",
//     "value2": 123
// }
```

### References

- [Eloquent JavaScript: Mutability](https://eloquentjavascript.net/04_data.html#h_C3n45IkMhg)
- [MDN: Mutable](https://developer.mozilla.org/en-US/docs/Glossary/Mutable)
- [MDN: Immutable](https://developer.mozilla.org/en-US/docs/Glossary/Immutable)


Thanks for reading, and see you next time! 👋

---

🗞️ **NEWSLETTER -** _If you want to hear about my latest articles and interesting software development content, [subscribe to my newsletter](https://mailchi.mp/22b236f812b1/subscribe-to-newsletter)._

🐦 **TWITTER -** *Follow me on [Twitter](https://twitter.com/DamianDemasi).*

<a href="https://www.buymeacoffee.com/damiandemasi" target="_blank"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641530738382/Wt_2bHGsXK.png" alt="Buy Me A Coffee" style="height: 40px !important;"></a>

_Cover photo by Ivana Cajina on Unsplash_