Joel Thoms
joel.net - JavaScript, ReactJS, and Node

joel.net - JavaScript, ReactJS, and Node

Const vs Immutable (Plus Shallow vs Deep)

Const vs Immutable (Plus Shallow vs Deep)

Joel Thoms's photo
Joel Thoms

Published on Feb 22, 2021

5 min read

Subscribe to my newsletter and never miss my upcoming articles

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 🍻

 
Share this