Blurt

Note About ES6 Constants

While reading up about housekeeping the global object in ECMAscript 6, I noticed a subtlety of const that could have escaped the attention of some software developers like myself so I’m writing this post especially to help me remember :bulb:… because I need to be careful for the seemingly immutable, yet capable of change.

Non-primitives such as arrays and objects are accessed through their pointers and constants to such items pertain to the reference and not the data referred to.

A constant array or object therefore always maintains its reference1, but the data pointed to by the immutable reference may be mutated.

const number = 12;
number++; // fails, integers are primitive

In the case of an array one may mutate the object referred to by use of the push, pop, shift and unshift functions as demonstrated in the following snippet:

const people = [];
people.push('Leni') // ok
people = []; // fails, don't reassign

The data referred to by an object reference may also be mutated:

const thing = {};
thing['name'] = 'Spaceship'; // ok
thing = { 'name': 'Paperplane' } // fails, don't reassign

Upon first glance it isn’t far fetched to assume that somewhere in the life cycle of a codebase, someone will mistake a constant for an item of immutable state. :warning:. Here is how I maintain sanity:

  • remember that primitives are passed by value
  • remember that non-primitives are passed by a copy of the reference2
  • always return copies to non-primitives, ensuring that no one has access to the data I need for my housekeeping, effectively giving me some guarantees regarding state.

Read

  1. The pointer never changes, meaning that it will always point to the same item in memory.

  2. As phrased by Alnitak in an answer to Does JavaScript pass by reference?