ECMAScript 6 Feature: Declaring Constants in JavaScript
Prior to ECMAScript 6 (ES6), we declared all variables using the var
keyword. As of ES6, we now have two new keywords to declare variables: let
and const
. In this post, I will discuss the const
keyword, which allows us to declare immutable variables.
***
Get quick JavaScript tips in your inbox by signing up for my free newsletter!
***
Achieve Variable Immutability Using Const
Declaring variables in JavaScript using var
allows for reassignment. Take the following example:
var foo = "bar";
foo = "baz";
console.log(foo);
// "baz"
If we don’t want to allow reassignment, we can use const
. In this case, reassignment with throw an error:
const foo = "bar"
foo = "baz";
// Uncaught TypeError: Assignment to constant variable.
Narrower Scoping Using Const
Another important difference between the var
and const
keywords is that variables defined with var
are function-scoped whereas variables defined with const
are block-scoped. Take the following example:
{
var a = "hello world";
const b = "foo bar";
}console.log(a);
// "hello world"console.log(b);
// Uncaught ReferenceError: b is not defined
In this example, since a
is a var
, its declaration is hoisted to the top of the function scope, which in this case is the same as the global scope. The console.log
is also in this scope and has access to a
. Since b
is a const
, its declaration is hoisted to the top of the block scope, which in this case is confined to the block {...}
in which it was declared.
Important Caveats or “Gotchas”
When used on Objects or Arrays (i.e., non-primitives), the const
keyword does not prevent mutation of properties or elements, respectively. Take the following examples:
const a = { foo: "bar" };
const b = [1, 2, 3];a.foo = "baz";
b.push(4);console.log(a);
// { foo: "baz" }console.log(b);
// [1, 2, 3, 4]
In both of these cases, a
and b
are indeed remaining constant: they are still referencing the same object and array in memory, respectively. If we need to ensure immutability of non-primitive types in JavaScript, we need to look elsewhere! A few options exist. One is to use Object.freeze
, which prevents mutation of an object’s properties, but it only does so shallowly (i.e., only one level deep). Another option is to use a package like deep-freeze, which applies Object.freeze
recursively down the object tree.
Thanks for reading and please let me know below if you have any questions!