Chainlink fence with many padlocks on it

Perhaps surprisingly, JavaScript has long lacked support for constants: that is, referenced values that don’t change throughout the execution of your script. For lack of any alternatives, most constants have been assigned to variables:

var DAYSINWEEK = 7;

This is both dangerous and impractical, since it allows the value of DAYSINWEEK to be changed at any time later in your script. Coders have developed various ways of trying to indicate that a JavaScript variable is actually constant: from writing the name in ALL CAPS (a best practice) to the solutions I will discuss below. Thankfully, the latest version of ECMAScript (the standardized specification that JavaScript is derived from) introduces a true constant:

const DAYSINWEEK = 7;

Thereafter DAYSINWEEK can be referred to like a variable, but can never change its value:

console.log(DAYSINWEEK);
> 7
DAYSINWEEK = 8;
> error

Once it is declared (constants must be initialized using const, and follow the same naming rules as variables), the constant’s name is reserved: you can’t name a variable DAYSINWEEK and have a constant with the same name, or vice-versa.

const has good support in recent browsers: IE11 and Edge, Firefox 31+, Opera 12+, Safari 5.1.7+, iOS 7 and higher, together with Chrome 36+. However, this support comes with some important provisions:

  1. Chrome does not throw an error if an overwrite is attempted. The value of the constant won’t be altered by any attempts to change it, but a naive coder might assume that a new value will be applied due to the lack of an error message.
  2. constants are not block-scoped in Webkit. That is, references to constants can “leak” outside their current scope.
  3. Firefox 35 and earlier allows you to change the value of const on the fly. This is fixed in Firefox 36+.
  4. Safari 10’s handling of const will cause a conflict if a const takes the same name as a predefined global variable from your markup. That is, if you have an element with the id of #inMediaRes in your page, you cannot use inMediaRes as the name of a constant… not even to reference the same element. Safari is prioritizing the fact that an id automatically turns into a reference in JavaScript, and is reserving the namespace.

It’s worth noting that Webkit’s issues only occur outside of strict mode (the subject of an upcoming article).

Is const Production-Ready?

The choice to use const in your code will depend on several factors: most significantly, the browser versions of site visitors, since a const declaration will be treated as a script error in browsers such as IE10. If you want to use const in development, but are not yet ready to roll it out into production, you have a few choices:

Option 1: Use a transpiler

Transpilers, as the name suggests, transform your code while compiling it into another language: this this case, from ES6 (the specification in which const appears) to ES5. This allows you to develop in the most recent version of the language, but push to production a version that is compatible in a far wider range of browsers. Addy Osmani has an excellent list of ECMAScript transpilers for your use.

Option 2: Define the constant as an object’s property

This will make the value read-only, although the method isn’t terribly elegant:

var week = (function() {
	var internal = {
	"days": "7"
	};
	return {
		get: function(name) { return internal[name]; }
	};
})();

console.log(week.get("days"));
> 7

Object technique courtesy of Burke, photograph by Anton Pree, licensed under Creative Commons.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.