Const vs Immutable (Plus Shallow vs Deep)

Const vs Immutable (Plus Shallow vs Deep)

ยท

5 min read

While const and immutability are related, they are two separate concepts. These concepts often get confused, so I thought it made sense to cover them together.

It is my goal to not simply give you definitions, which are often forgotten. Instead, give you the intuition to understand the differences and why they work the way they do.

First, let's start by visualizing code the way I do.

๐Ÿง  How I Visualize Code

When I see code, I visualize the shape and connections of that code in my head. For example, this line of code...

var url = "https://joel.net"

I visualize my Application which contains a variable named url. url points to an object of type String that contains the value. The nature of a String is immutable, represented by the ๐Ÿ”’.

image.png

Because the url does not have a lock, the value can be re-assigned later.

Const Prevents Re-assignment of Variables

Declaring a variable with const, prevents the re-assignment of that value. The value can be only be assigned during declaration.

Let's look at some code.

const cat = {
  name: "Mojo",
  age: 11
}

This code can be visualized as:

image.png

The Application contains a variable named cat. cat is const and cannot be re-assigned later. Notice the ๐Ÿ”’ on cat.

cat points to an Object that contain the properties name (String) and age (Number). These values can be changed because JavaScript objects are mutable by default.

The nature of a String and Number are immutable so they're also flagged with a ๐Ÿ”’.

Making Object Immutable

Objects in JavaScript are mutable, meaning they are open to modification. To make a JavaScript object immutable (read-only) use the Object.freeze() method. There is also Object.seal(), which we won't be covering here. But please do research on your own.

const cat = {
  name: "Mojo",
  toys: ["Ball", "Feather"]
}

Object.freeze(cat)

image.png

Object.freeze() adds a ๐Ÿ”’ flag to the Object that cat points to. Notice here how toys points to an Array, which is mutable.

This means that while name and toys cannot be re-assigned, toys.push("New Toy") is valid because the Array is not immutable.

This is because Object.freeze() is a shallow operation, applying the freeze to only the Object.

Deep Freezing Objects

Because Object.freeze() is a shallow operation, applying only to the Object and not the children, a recursive function must be created to also apply Object.freeze() to those children.

// from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
function deepFreeze(object) {
  // Retrieve the property names defined on object
  const propNames = Object.getOwnPropertyNames(object);

  // Freeze properties before freezing self
  for (const name of propNames) {
    const value = object[name];

    if (value && typeof value === "object") {
      deepFreeze(value);
    }
  }

  return Object.freeze(object);
}

With deepFreeze, we can now deep freeze JavaScript objects.

const cat = {
  name: "Mojo",
  toys: ["Ball", "Feather"]
}

deepFreeze(cat)

With deepFreeze applied to cat, the ๐Ÿ”’ flag is now applied to Array indicating it is now immutable.

cat is now constant and deeply immutable ๐Ÿ”ฅ

image.png

Summary

  • const prevents the re-assignment of variables.
  • Object.freeze will shallow freeze an object.
  • A custom function must be created to deep freeze objects.

Subscribe to my Newsletter to continue learning about Cloudflare Workers!

Cheers ๐Ÿป