logo
Published on

The const keyword does not create immutable variables

Authors

An introduction to the const keyword

The value of a variable created with the const keyword can't be changed. Although this statement is true in the case of primitive values, it is complicated when it comes to objects and arrays.

For objects and arrays, only the reference to the memory location that contains the data is stored in the variable. So the data underneath can be changed without changing the reference

Example:

const foodsILike = ['Shwarma']
foodsILike.push('Jalebi')
console.log(foodsILike) // => ["Shwarma", "Jalebi"]

In this example, we created an array with the const keyword and were still able to add items to it

What is immutability and why is it important?

Functional programming techniques and design patterns are very common in the Javascript world. We have tools like RxJS which bring reactivity to Javascript. Redux also depends on its state to be immutable. As a JS developer, you must take care that you do not mutate the state directly while updating it. In Redux, our reducers are never allowed to mutate the original / current state values!.

To prevent issues like these from occurring, you want to make your data immutable.

Using the Object.freeze() method

The Object.freeze() method freezes an object (duh!). What does this exactly mean? A frozen object cannot be edited. New properties cannot be added and existing properties cannot be removed or modified in any way.

'use strict'
const obj = {
prop: 42,
}
Object.freeze(obj)
obj.prop = 33
// => TypeError: "prop" is read-only
// => will fail silently in non strict mode

There is however, a flaw to this approach

'use strict'
const obj = {
prop: 42,
propObject: {
name: null,
},
}
Object.freeze(obj)
obj['propObject']['name'] = 'Burhan'
console.log(obj)
/**
{
prop: 42,
propObject: {
name: "Burhan"
}
}
*/

This works perfectly fine since we are not modifying any properties of the frozen object directly.

You could use the deep-freeze package that recursively freezes all your objects

var deepFreeze = require('deep-freeze')
deepFreeze(Buffer)
Buffer.x = 5
console.log(Buffer.x === undefined)
Buffer.prototype.z = 3
console.log(Buffer.prototype.z === undefined)
/**
true
true
*/

This will help you prevent issues with mutations

Conclusion

The const keyword creates a read-only reference to a value. It does not mean that the value itself is immutable. It's just that the variable identifier cannot be reassigned

If you plan on using immutable objects with React or Redux, check out ImmerJS. It enables you to create new objects without writing extra code for deep clones. It also has some great utility hooks to use with React

Share: