The argument for const

Lately as my team moves towards a mandatory ES6 development cycle, we often go into arguments about which keyword to use to declare a variable. As outlined in my previous blog, ES6 brings 2 new variable declaration keywords to javascript: namely let and const. Both are new to ES6. Both are block scoped. Both are in the temporal dead zone while hoisted and waiting to be declared.

The argument then is, when do we use const over let? #

This stirs the pot quite a bit since we have eslint installed using a unified linter config (spoiler alert: it’s the de facto standard Airbnb style guide). My position is to use const over let when possible. As is the position of many others in the industry.

“use const by default, let only where it is required and var to identify code which needs to be refactored”

Rose Edwards

Immutability of const #

The idea of course is to in the end achieve immutability in the web. const inherently gives us some of these properties on primitives. The example below shows how the variable harry would not be changed at the second statement. (Hint: this will throw an error if in strict mode).

const harry = 'potter';
harry = 'weasley'; // Error in strict mode
console.log(harry); // 'potter'

As we can see, at least for strings and numbers (primitives in js), const provides a level of immutability by design. But what about the other basic blocks of javascript? - namely, arrays and objects. Arrays and objects when declared as a const can actually be changed in a certain way. If you look at the example below, an array of hogwartsStudents can be changed by adding or removing items but it cannot be reassigned to Durmstrang students.

const hogwartsStudents = [];
hogwartsStudents.push('Hermione');
hogwartsStudents; // ['Hermione']

hogwartsStudents = ['Krum', 'Igor']; // Error in strict mode
hogwartsStudents; // ['Hermione']

The reasoning for this behaviour is that a const of hogwartsStudents is a reference to a block of memory for the array. We can still use that reference but we cannot reassign the reference to a new object or array.

What if we want the object properties and the array values to be immutable? #

There are various ways to do this ranging from Facebook’s immutable.js project to using new ES6 functions such as Object.freeze() and Object.seal.

Object.seal(objectArg) stops properties from being added or deleted but it does not stop one from modifying the object’s properties.

Object.freeze(objectArg) stops properties from being added, deleted, or modified making it totally immutable (well except for properties that are arrays or objects since like in the const scenario, they are merely references).

const spellBook = {
    'charms': {
        'accio': true
    },
    'curses': ['tarantallegra'],
    'ownedBy': 'Half Blood Prince'
};
Object.freeze(spellBook); // changed in place

spellBook.ownedBy = 'Harry Potter';
// Throws an error in strict mode
// Or fails silently otherwise

console.log(spellBook.ownedBy); // 'Half Blood Prince'

spellBook.charms.portego = true;
// Works since spellBook.charms is not frozen

spellBook.charms;
// { 'accio': true, 'portego': true}

The case for Immutability #

Pros

Cons

Much of what makes application development difficult is tracking mutation and maintaining state. Developing with immutable data encourages you to think differently about how data flows through your application.

Immutable.js

 
7
Kudos
 
7
Kudos

Now read this

ES6 Reflect API

This is the part of a series of blogs on the new features on the upcoming ECMAScript 6 (ES6) specification which JavaScript implements. In this blog we focus on the Reflect API introduced in ES6. Reflect Object # What is the Reflect API?... Continue →