DEV Community

Valentino Gagliardi
Valentino Gagliardi

Posted on

Once and for all: const in JavaScript is not immutable

I know that's been said hundred of times, but I still see people proclaiming (even in some JavaScript books) that const is immutable. It is not.

const in JavaScript is not immutable

In JavaScript, values can be stored in a variable with the var keyword, the most compatible way for declaring variables:

var greet = "Hello";
var year = 89;
var not = false;
Enter fullscreen mode Exit fullscreen mode

I said compatible because with ECMAScript 2015 we have two other options: let and const. Older browsers may not support these new keywords and unless using a "transpiler" like Babel you may run into errors. In newer browser instead you can reap the benefits of let and const which differ from var in two ways:

  • both let and const create their own "bubble" (scope)
  • const cannot be re-assigned, nor re-declared

By "bubble" I mean that a variable declared with let or const do not overlap with the same variable name declared in an enclosing or in an outer "bubble". For example:

let name = "John";

{
  let name = "Valentino";
  console.log(name); // "Valentino"
}

console.log(name); // "John"
Enter fullscreen mode Exit fullscreen mode

Here name seems a duplicate, but in reality it is two different variables in their own bubble. const has the same behaviour:

const name = "John";

{
  const name = "Valentino";
  console.log(name); // "Valentino"
}

console.log(name); // "John"
Enter fullscreen mode Exit fullscreen mode

The same code with var instead behaves in a different way:

var name = "John";

{
  var name = "Valentino";
  console.log(name); // "Valentino"
}

console.log(name); // "Valentino"
Enter fullscreen mode Exit fullscreen mode

As I said const cannot be reassigned, nor re-declared in the same bubble. If you try to re-declare a const you get "SyntaxError: Identifier has already been declared". And if you reassign some value to the same constant you get "TypeError: Assignment to constant variable". The following example throws an error:

const name = "John";
const name = "Valentino";

// SyntaxError: Identifier 'name' has already been declared
Enter fullscreen mode Exit fullscreen mode

and this code throws as well:

const name = "John";
name = "Valentino";

// TypeError: Assignment to constant variable.
Enter fullscreen mode Exit fullscreen mode

But please, pay attention because when we say "const cannot be reassigned, nor re-declared" that does not mean const is immutable. That's a topic that trips up literally every JavaScript developer I talk to. In fact any slightly more complex JavaScript data structure like array or object is more than mutable even when assigned to a const:

const person = {
  name: "John",
  age: 21
};

person.name = "Valentino";

console.log(person);

// { name: 'Valentino', age: 21 }
// Oh, I wish I was 21 for real!
Enter fullscreen mode Exit fullscreen mode

How is that immutable? Here's an array:

const list = [1, 1, 3, 2, 5];

list.shift();

console.log(list); // [ 1, 3, 2, 5 ]
Enter fullscreen mode Exit fullscreen mode

Again, not immutable. Next time someone says "const is immutable", show him/her a couple of tricks.

Happy coding!

Top comments (13)

Collapse
 
itsjzt profile image
Saurabh Sharma

The thing is const never let you to change the memory address it refers to.

you but can mutate the value itself.

Collapse
 
skhmt profile image
Mike 🐈‍⬛

Const makes the reference immutable, and for primitives that means the value is immutable too.

But for Objects, the difference matters.

Collapse
 
valentinogagliardi profile image
Valentino Gagliardi

yes!

Collapse
 
prahladyeri profile image
Prahlad Yeri

That's just because of the nature of JavaScript, that's how it is.

In JavaScript, some built-in types (numbers, strings) are immutable, but custom objects are generally mutable.

So, it matters not whether you've declared them as const or not, what matters is whether they are custom objects (like in your example) or simple numbers/strings. The latter are obviously immutable whether you use const or not.

And even with your custom object, you can make individual attributes immutable like this (again, const doesn't matter here):

Object.defineProperty(person, 'name', { value: 'John', writable: false });

So when you do this, it'll be silently ignored since the person object is now immutable:

person.name = "Valentino";

This is irrespective of whether you defined person as let, const or var!

Collapse
 
valentinogagliardi profile image
Valentino Gagliardi

My point is that there are people out there still saying "const is intrinsically immutable". While it's not. As for objects >> Protecting objects from manipulation

Collapse
 
nicknapoli82 profile image
Nicholas Napoli • Edited

I would argue that const is intrinsically immutable. Posing the argument that making a reference immutable, but the data inside is not, is not relevant. Granted. It would be nice if this were default behavior, but knowing why the data inside is not const is important.

This flows down to the engine that js is running on in lower level language land, and that land explains this concept of why well. It should not be a debate.

Collapse
 
georgecoldham profile image
George

If you want immutability then you need to start using Object.freeze() and Object.seal()

Collapse
 
valentinogagliardi profile image
Valentino Gagliardi

Object.freeze is shallow though :-)

Collapse
 
itsjzt profile image
Saurabh Sharma • Edited

So that's why there libraries like Immutable.js, but it would be great if JS has something for making values immutable.

Collapse
 
thebuzzsaw profile image
Kelly Brown

It's all a war of semantics. Technically, the variable itself is immutable for its lifetime; it just so happens to act as a gateway to data that is quite mutable. This is why I hate the way Java tries to teach students: "Everything is pass by value." Yeah, everything is pass by value... but the value happens to be a reference to something else. Strange that something passed by "value" lets me trigger side effects for observers of that data.

Good post.

Collapse
 
conectado profile image
Conectado

I think const as an immutable pointer. You can change the value of what it points to but not the place it points to.

Disclaimer, that is just how I think about it, I don't know if it works like that internally.

Collapse
 
laas29_97 profile image
laas29

We have to be sure what exactly const are pointing to, the memory address remains the same.

Collapse
 
ben profile image
Ben Halpern

I just learned so much