const is excellent. It allows us to keep our variables in controlled scope, and reduces errors caused by the case of mistaken reassignments.

But it can also lead to a false sense of security. Not everything is truly immutable when defined by const.

Consider this simple example -

const x = 1;
x = 2; // TypeError: Assignment to constant variable.

This is applicable for other types of variables, or to simpler objects created on top of these primitives.

const x = new Number(1);
x = 2; // TypeError: Assignment to constant variable.

But the behaviour is not as expected when you are dealing with strings or objects. You cannot reassign value, sure - but you can change existing value.

const arr = [0, 1];

// arr = [0]; // error

arr.push(2); // sure, why not
console.log(arr); // [ 0, 1, 2 ]

You can create an immutable object but it needs an additional step.

const arr = [0, 1];

Object.freeze(arr);
arr.push(3);
// TypeError: Cannot add property 3, object is not extensible

The same is applicable for other types of complex objects as well.

const earth = { name: "earth", position: 3 };
earth["position"] = 2; // will change the way of this solar system, but ok
console.log("earth: ", earth); // { name: 'earth', position: 2 }

Object.freeze(earth);
earth["position"] = 3;
console.log("earth: ", earth); // { name: 'earth', position: 2 }
// no change: venus is screwed