Constants In JavaScript (and all that bulls**t)
Tags: javascript, node, typescript
Published: 2020-03-18 17:10:00

If you have been programming in JavaScript for a little while you'd have noticed that `const` in JavaScript does not mean you can't change it. There's also no memory, performance or any other benefit. WTF!

Okay, okay. Look at this piece of code:

```js
const toastStatus = "burnt"; // why though?
// let's change this
toastStatus = "not ok";
```

You will be expecting that it will give an error, right? Yup. You are right. It does give this error:

> `Uncaught TypeError: Assignment to constant variable.`

So far so good. Let's say we want to give an `id` to the toast status:

```js
const toast = {
    id: "da_best_toast",
    status: "burnt"
};
```

And something happens and this toast suddenly becomes unburnt (accidentally of course):
```js
toast.status = "all ok"
```

You'd be an expecting the same old error, right? But guess what? No error. Not even a hint. It's all okay (as the toast said). WTF! Same is the case with any `Object` (i.e. Arrays, Objects, Classes, Functions etc. etc.)

**WTF!!**

Okay, okay. I guess that's a good enough rant for now. SO what's the problem?

## The Problem

Nothing is immutable in JavaScript. Nothing is unchangable in JavaScript. Anything can become anything in JavaScript. That's why you have TypeScript but even then there are some quirks in JavaScript that will make you pull your hair out.

So what do we do if we want perfect immutability? Such that no one can change the object. At all?

You could use a third-party library like: `Immutable-Js` or `immer`. But why? Why, why, why? When JavaScript can do it but for some reason doesn't do it by default (via the `const` keyword)?

If you haven't noticed by now: Objects are extensible in JavaScript. Meaning you can add, delete or edit without any restriction. Any Object. Even the standard ones like `global` or `window`. Now, I understand that that is a cool thing and all but it has many, many disadvantages. So let's try to make our objects...constant.

## The Solution..s

### `Object.freeze`:

From MDN:

> The Object.freeze() method freezes an object. A frozen object can no longer be changed; freezing an object prevents new properties from being added to it, existing properties from being removed, prevents changing the enumerability, configurability, or writability of existing properties, and prevents the values of existing properties from being changed. In addition, freezing an object also prevents its prototype from being changed. freeze() returns the same object that was passed in.

I think you got the point. It makes your object unchangable. Forever.

Here's the same example as above:

```js
const toast = Object.freeze({
    id: "da_best_toast",
    status: "burnt"
});
```

Now if you wanted to change the status like this:

```js
toast.status = "all ok"
```

It will give this error (be a good kid and turn on `strict mode`):

> `TypeError: Cannot assign to read only property 'done' of object '#<Object>'`

And later if you accidentally add another property:

```js
toast.bread = "baba bread";

```
It will give another error:

> `TypeError: Cannot add property bread, object is not extensible`

And then if you try and delete the `status` (accidentally, of course):

```js
delete toast.status
```

You'd get:

> `TypeError: Cannot delete property 'done' of #<Object>`

In this way you can make any Object immutable. You could also write a utility function like this, to make it a bit flashier:

```js
function im(obj){
    return Object.freeze(obj)
}

// and then use it like so:

const immutable = im({ data: "some_data" });
```

And if you wanted to check whether an object is frozen, simply do:

```js
Object.isFrozen(toast); // === true
```
----------

Now what if you wanted to only disallow new properties from being added/deleted but allow existing properties from being changed. In other words, what if you wanted "partial" immutability?

Well, for that you have:

### `Object.seal`:

From MDN:

> The `Object.seal()` method seals an object, preventing new properties from being added to it and marking all existing properties as non-configurable. Values of present properties can still be changed as long as they are writable.

So basically, it will only allow existing properties from being edited (not deleted). Let's see an example.

```js
const network = Object.seal({
    stable: true,
    speed: "50mbps",
    status: "connected"
});

// let's suppose, the network is disconnected suddenly, you'd simply do:
network.status = "disconnected";

// however if you wanted to add upstream speed, it will throw:
network.upstream = "25mbps";

// or if you try and delete, it will also throw.
delete network.stable
```

You can easily check if an object is sealed or not using:

```js
Object.isSealed(network); // === true
```
----------------

So far so good. But what if you wanted to disallow only additions but allow edits and deletions? For that you have `Object.preventExtensions`.

### `Object.preventExtensions`

From MDN:

> The `Object.preventExtensions()` method prevents new properties from ever being added to an object (i.e. prevents future extensions to the object).

Let's see an example:

```js
const person = Object.preventExtensions({
    name: "Baker Yota",
    age: 35,
});

// now let's say you wanted to add a new property, it will throw.
person.father = "Samhil Yota"

// But you can edit the age:
person.age = 36;

// And delete it too:
delete person.age;
```

And if you wanted to check whether an object is extensible or not, simply do:

```js
Object.isExtensible(person); // === false
```
--------------

So there you have it: **Immutability in JavaScript**.

## Notes:

1. Objects that are manipulated in this way do not have their references altered. So `frozen_object === real_object` gives `true`.
2. You can put in any kind of `Object`. Be it an `Array`, `Function`, `Class` etc.

## Conclusion:

Javascript is a nice language but it does have some wacky areas a beginner would not be expecting. Hopefully, this little lesson in immutability will have made you understood that area of "science". Now don't be annoying and give me a reaction. :D Just joking. But seriously, do leave a comment with your thoughts.

Thanks for reading,
thecodrr

**P.S. Here is my latest project in case you are interested:**

{% github thecodrr/fdir %}