Damian Demasi
Damian Demasi's Blog

Follow

Damian Demasi's Blog

Follow
Navigating Mutability and Reference Issues in JavaScript

Navigating Mutability and Reference Issues in JavaScript

Damian Demasi's photo
Damian Demasi
ยทFeb 27, 2023ยท

4 min read

Table of contents

  • Mutability
  • Primitive values are immutable
  • Objects are mutable
  • The reference confusion in objects
  • References

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.

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):

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:

// 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.

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:

// 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.

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.

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:

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

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.

๐Ÿฆ TWITTER - Follow me on Twitter.

Did you find this article valuable?

Support Damian Demasi by becoming a sponsor. Any amount is appreciated!

See recent sponsors |ย Learn more about Hashnode Sponsors
ย 
Share this