Marius Schulz
Marius Schulz
Front End Engineer

Constant Variables in JavaScript, or: When "const" Isn't Constant

ECMAScript 2015 introduced the let and const keywords as alternatives to var, which JavaScript has always had. Both let and const declare local variables with block scope rather than function scope. In addition, const provides some notion of constancy, which let doesn't.

Unfortunately, the name of the const keyword might be misleading. In JavaScript, const does not mean constant, but one-time assignment. It's a subtle yet important distinction. Let's see what one-time assignment means:

// We're declaring PI to be a constant variable.
const PI = 3.141592653589793;

// Any attempt to assign a new value to PI
// fails because PI is a constant variable.
PI = 0;
PI++;

// All of the variable declarations below fail
// because we can't declare a new variable with the
// same identifier as an existing constant variable.
var PI = 0;
let PI = 0;
const PI = 0;

However, variables declared using the const keyword do not generally have a truly immutable value. Remember, const does not mean "constant", it means one-time assignment. The part that's constant is the reference to an object stored within the constant variable, not the object itself. The following example illustrates the difference:

// We're declaring a constant variable
// to hold a settings object.
const settings = {
  baseUrl: "https://example.com",
};

// Since `settings` is a constant variable,
// an attempt to assign a new value will fail.
settings = {};

// However, the object is **not** immutable.
// This means we can change its properties!
settings.baseUrl = "https://evil.example.com";

Declaring a variable to be constant doesn't make the objects it references immutable, as the above example shows. Object properties can change or be deleted altogether. The same goes for arrays assigned to a constant variable; Elements can be added, removed, reordered, or modified:

const numbers = [1, 2, 3];
numbers.push(4);
numbers.shift();

// numbers = [2, 3, 4]

For the sake of completeness, it is possible to create true constants in some cases. If a primitive value (such as a string, number, or boolean value) is assigned to a constant variable, that variable will be a true constant. Our PI constant is an example for this. There's no way to modify the value of the numeric literal 3.141592653589793 after it has been assigned.

To make an object truly immutable, you can pass it to the Object.freeze function to prevent any changes to its properties. Be aware that freeze is shallow, so you'll have to recursively call it for nested objects if you want the entire object tree to be frozen. If you need immutable data structures, it might be safer and more convenient to use a library such as Facebook's Immutable.js which is specifically made for this purpose.