Keyword 'const' does not make the value immutable. What does it mean?

JavascriptEcmascript 6Constants

Javascript Problem Overview


There's the const definition in Exploring ES6 by Dr. Axel Rauschmayer:

> const works like let, but the variable you declare must be > immediately initialized, with a value that can’t be changed > afterwards. […] > > const bar = 123; > bar = 456; // TypeError: bar is read-only

and then he writes

> **Pitfall: const does not make the value immutable** > > const only means that a variable always has the same value, > but it does not mean that the value itself is or becomes immutable.

I am little confused with this pitfall. Can any one clearly define the const with this pitfall?

Javascript Solutions


Solution 1 - Javascript

When you make something const in JavaScript, you can't reassign the variable itself to reference something else. However, the variable can still reference a mutable object.

const x = {a: 123};

// This is not allowed.  This would reassign `x` itself to refer to a
// different object.
x = {b: 456};

// This, however, is allowed.  This would mutate the object `x` refers to,
// but `x` itself hasn't been reassigned to refer to something else.
x.a = 456;

In the case of primitives such as strings and numbers, const is simpler to understand, since you don't mutate the values but instead assign a new value to the variable.

Solution 2 - Javascript

MDN sums it up nicely:

> The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned. For instance, in case the content is an object, this means the object itself can still be altered.

More succinctly: const creates an immutable binding.

In other words: const, like var, gives you a mutable chunk of memory in which you're storing something. However, const dictates that you must keep referring to that same chunk of memory – you can't reassign the variable to a different chunk of memory, because the variable reference is constant.

To really make something constant and unchanging after you've declared it, you need to use something like Object.freeze(). However, that's shallow and only works on key/value pairs. Freezing an entire object takes a bit more effort. To do so repeatedly in a performant way is yet more challenging. If you really have a need for that, I'd recommend checking out something like Immutable.js

Solution 3 - Javascript

Rebinding

const and let declarations control whether rebindings (aka reassignments) between identifiers and values are allowed:

const x = "initial value";
let y = "initial value";

// rebinding/reassignment

try { x = "reassignment" } catch(e) { console.log(x) } // fails

y = "reassignment"; // succeeds
console.log(y);

Immutability

Immutability is controlled at the type level. Object is a mutable type, whereas String is an immutable type:

const o = {mutable: true};
const x = "immutable";

// mutations

o.foo = true; // succeeds
x[0] = "I"; // fails

console.log(o); // {mutable: true, foo: true}
console.log(x); // immutable

Solution 4 - Javascript

const means: you can't change the initially assigned value.

First, define, what is a value in js. Value can be: Booleans, strings, numbers, objects, functions, and undefined values.

Like: People are calling you with your name, it's not changing. However, you change your clothes. The binding between the people and you is your name. The rest can change. Sorry for the weird example.

So, let me give you some examples:

// boolean
const isItOn = true;
isItOn = false;           // error

// number
const counter = 0;
counter++;                // error

// string
const name = 'edison';
name = 'tesla';           // error

// objects
const fullname = {
  name: 'albert',
  lastname: 'einstein'
};

fullname = {              // error
  name: 'werner',
  lastname: 'heisenberg'
};

// NOW LOOK AT THIS:
//
// works because, you didn't change the "value" of fullname
// you changed the value inside of it!
fullname.name = 'hermann';

const increase = aNumber => ++aNumber;
increase = aNumber => aNumber + 1;      // error

// NOW LOOK AT THIS:
//
// no error because now you're not changing the value
// which is the decrease function itself. function is a
// value too.
let anotherNumber = 3;
const decrease = () => --anotherNumber;

anotherNumber = 10;             // no error
decrease();                     // outputs 9

const chaos = undefined;
chaos = 'let there be light'    // error

const weird = NaN;
weird = 0                       // error

As you can see, unless you're not changing the "first" assigned value to a const, no error. Whenever you try to change the first assigned value to something else, it gets angry, and it gives an error.

So, this is the second thing you might know when using const. Which is, it should be initialized to a value on its declaration or it will be angry.

const orphan;                    // error
const rich = 0;                  // no error

Solution 5 - Javascript

ES6/ES2015 const keyword:

The const keyword is used to declare a block scoped variable (like declaring with let). The difference between declaring a variable with const and let is the following:

  1. A variable declared const cannot be reassigned.
  2. A variable declared with const has to be assigned when declared. This is a logical consequence of the previous point because a variable declared with const cannot be reassigned, that's why we have to assign it exactly once when we declare the variable.

Example:

// we declare variable myVariable
let myVariable;

// first assignment
myVariable = 'First assingment';
// additional assignment
myVariable = 'Second assignment';

// we have to declare AND initialize the variable at the same time
const myConstant = 3.14;

// This will throw an error
myConstant = 12;

In the above example we can observe the following:

  1. The variable myVariable declared with let can first be declared and then be assigned.
  2. The variable myConstant declared with const has to be declared and assigned at the same time.
  3. When we try to reassign the variable myConstant we get the following error:

> Uncaught TypeError: Assignment to constant variable

Caveat: The variable assigned with const is still mutable:

A variable declared with const just can't be reassigned, it is still mutable. Being mutable means that the data structure (object, array, map, etc) which was assigned to the const variable still can be altered (i.e. mutated). Examples of mutation are:

  1. Adding/deleting/altering a property of an object
  2. Changing the value of an array at a specific array index

If really want an object to be not mutable you will have to use something like Object.freeze(). This is a method which freezes an object. A frozen object can no longer be changed and no new properties can be added.

Example:

const obj = {prop1: 1};

obj.prop1 = 2;
obj.prop2 = 2;

console.log(obj);

// We freeze the object here
Object.freeze(obj);

obj.prop1 = 5;
delete obj.prop2;

// The object was frozen and thus not mutated
console.log(obj);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMukund KumarView Question on Stackoverflow
Solution 1 - JavascriptCandy GumdropView Answer on Stackoverflow
Solution 2 - JavascriptMike PostView Answer on Stackoverflow
Solution 3 - Javascriptuser6445533View Answer on Stackoverflow
Solution 4 - JavascriptInanc GumusView Answer on Stackoverflow
Solution 5 - JavascriptWillem van der VeenView Answer on Stackoverflow