Learn the JavaScript Proxy Object: Creating Immutable Objects
Tags: javascript, webdev, tutorial, react
Published: 2020-06-02 11:57:18

---
title: Learn the JavaScript Proxy Object: Creating Immutable Objects
published: true
description: In this post, we roll our own immutable proxy function to prevent object mutation!
tags: javascript, webdev, tutorial, react 
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/59lsay7uvkhcmu22z7tj.jpg
canonical_url: https://typeofnan.dev/roll-your-own-javascript-immutability-function-using-the-proxy-object/
---

While JavaScript allows us to mutate objects, we might choose to not allow ourselves (and fellow programmers) to do so. One of the best examples of this in the JavaScript world today is when we're setting state in a React application. If we mutate our current state rather than a new copy of our current state, we can encounter hard-to-diagnose issues.

In this post, we roll our own immutable proxy function to prevent object mutation!

<hr />

## If you enjoy this post, please give it a 💓, 🦄, or 🔖 and consider:

- signing up for [my free weekly dev newsletter](https://buttondown.email/devtuts)
- subscribing to [my free YouTube dev channel](https://www.youtube.com/c/devtutsco?sub_confirmation=1)

<hr />

# What is Object Mutation?

As a quick refresher, object mutation is when we change a property on an object or array. This is very different from _reassignment_, in which we point a different object reference altogether. Here are a couple examples of mutation vs. reassignment:

```javascript
// Mutation
const person = { name: "Bo" };
person.name = "Jack";

// Reassignment
let pet = { name: "Daffodil", type: "dog" };
pet = { name: "Whiskers", type: "cat" };
```

And we have to keep in mind this applies to arrays as well:

```javascript
// Mutation
const people = ["Jack", "Jill", "Bob", "Jane"];
people[1] = "Beverly";

// Reassignment
let pets = ["Daffodil", "Whiskers", "Ladybird"];
pets = ["Mousse", "Biscuit"];
```

# An Example of Unintended Consequences of Object Mutation

Now that we have an idea of what mutation is, how can mutation have unintended consequences? Let's look at the following example.

```javascript
const person = { name: "Bo" };
const otherPerson = person;
otherPerson.name = "Finn";

console.log(person);
// { name: "Finn" }
```

Yikes, that's right! Both `person` and `otherPerson` are referencing the same object, so if we mutate `name` on `otherPerson`, that change will be reflected when we access `person`.

Instead of letting ourselves (and our fellow developers on our project) mutate an object like this, what if we threw an error? That's where our immutable proxy solution comes in.

# Our Immutable Proxy Solution

The JavaScript `Proxy` object is a handy bit of meta programming we can use. It allows us to wrap an object with custom functionality for things like getters and setters on that object.

For our immutable proxy, let's create a function that takes an object and returns a new proxy for that object. when we try to `get` a property on that object, we check if that property is an object itself. If so, then, in recursive fashion, we return that property wrapped in an immutable proxy. Otherwise, we just return the property.

When we try to `set` the proxied object's value, simple throw an error letting the user know they can't `set` a property on this object.

Here's our immutable proxy function in action:

```javascript
const person = {
  name: "Bo",
  animals: [{ type: "dog", name: "Daffodil" }],
};

const immutable = (obj) =>
  new Proxy(obj, {
    get(target, prop) {
      return typeof target[prop] === "object"
        ? immutable(target[prop])
        : target[prop];
    },
    set() {
      throw new Error("Immutable!");
    },
  });

const immutablePerson = immutable(person);

const immutableDog = immutablePerson.animals[0];

immutableDog.type = "cat";
// Error: Immutable!
```

And there we have it: we're unable to mutate a property on an immutable object!

# Should I Use This In Production

No, probably not. This kind of exercise is awesome academically, but there are all sorts of awesome, robust, and well-tested solutions out there that do the same thing (e.g., ImmutableJS and ImmerJS). I recommend checking out these awesome libraries if you're looking to include immutable data structures in your app!

<hr />

## If you enjoy this post, please give it a 💓, 🦄, or 🔖 and consider:

- signing up for [my free weekly dev newsletter](https://buttondown.email/devtuts)
- subscribing to [my free YouTube dev channel](https://www.youtube.com/c/devtutsco?sub_confirmation=1)

<hr />