In programming you can assign values to variables. In some languages, you can also assign values to constants. What’s the difference? The values of variables can vary (which is why they’re called variables), but the values of constants can’t. In other words, you can change the value of a variable all you want, but once you’ve assigned an initial value to a constant, you can’t change it again. Its value stays constant.

Many programming languages have constants as well as variables, but JavaScript doesn’t. That’s going to change soon. The working draft of the ECMAScript version 6 specification – the document that specifies the features that JavaScript implements – includes a way to create constants, with the const keyword. const is already implemented in the most recent versions of some of the major browsers.

Defining constants

Let’s give const a try in the Chrome (version 40) browser:

> const x = 3;
undefined

> x
3

> x = 4;
4

> x
3

You define a constant just like you do a variable, except you use the const keyword instead of var. Once you’ve initialized the constant, you can’t change it. Notice that when we tried to assign a new value, 4, to x the console responded with the value 4, which kind of makes it look like the statement worked, but it didn’t; the value of x is still 3. However, also notice there’s no error message.

Let’s run this same code in Safari (version 8):

> const x = 3;
undefined

> x
3

> x = 4;
4

> x
4

Interesting! Safari doesn’t give us an error message when we use the const keyword but also doesn’t prevent us from changing the value… so x is not really a constant. It’s a variable.

How about Firefox (version 35)?

> const x = 3;
undefined

> x
3

> x = 4;
4

> x
3

In Firefox, we get the expected behavior: a constant whose value we’re not allowed to change. Good!

In IE 11, using const doesn’t give us an error message, but if you try to access the value of the constant, you do get an error message:

> const x = 3;
undefined

> x

‘x’ is undefined

Attempting to change the value of a constant

Let’s see what happens if we try to redefine constants or even try to change them to variables with a series of experiments (Chrome 40):

If you declare the constant x:

> const x = 4;

and then try to declare it again:

> const x = 10;

you’ll get an error (in Chrome 40):
TypeError: Identifier ‘x’ has already been declared

In Firefox, you’ll also get an error:
TypeError: redeclaration of const x

So, not only does the browser prevent you from changing the value of a constant, it also prevents you from redeclaring it. What do you think happens if you try to redeclare x as a variable instead?

> const x = 10;
undefined

> x
10

> var x = 3;
undefined

> x
10

In this case (in both Chrome and Firefox), we don’t see an error, but we do see that the value of x hasn’t changed. Interesting.

Finally, what if we go the opposite way?

> var y = 100;
undefined

> y
100

> const y = 200;

If you do this, you’ll again get a type error in both Chrome and Firefox:
TypeError: Identifier ‘y’ has already been declared (in Chrome) and
TypeError: redeclaration of var y (in Firefox).

It’s important to be aware of these results as you begin to work with constants so you know whether to expect an error or not if you do the “wrong thing” with a constant. This will help you track down potential problems in your code.

Objects as constants

Next, let’s take a quick look at what happens when you declare an object as a constant:

> const o = {
   x: 3,
   y: 4
};
undefined

> o
Object {x: 3, y: 4}

> o = { z: 100 };
Object {z: 100}

> o
Object {x: 3, y: 4}

So far, so good: we’ve defined an object o and we’re not allowed to change o’s value (although, just like before, we don’t get an error message if we try). But what about the properties of o? Can we change those? Let’s try:

> o.z = o.x + o.y;
7

> o
Object {x: 3, y: 4, z: 7}

> o.x = 10;
10

> o
Object {x: 10, y: 4, z: 7}

> delete o.x;
true

> o
Object {y: 4, z: 7}

So, while we can’t give o a new value directly (in other words, we can’t create a whole new object and assign it to o), we can completely change the object o by modifying its properties, and adding or deleting properties. So what’s protected by o being a constant is the object reference, not the properties of the object (if you need a referesher on object references, check out Chapter 5 in Head First JavaScript Programming).

Is there a way to protect not just the object reference, but the property values as well? Yes, there is: with property descriptors. This is a fairly new feature added to JavaScript in the previous version (ECMAScript 5.1), and is now available in all the major browsers. It’s a topic worthy of its own blog post; the upshot is that you can use property descriptors to set attributes on an object’s properties effectively preventing an object’s individual properties from being changed or deleted, as well as preventing new properties from being added to the object.

Why use constants?

At this point, you might be wondering: why would I need to use a constant? If I have a value that doesn’t change, say… the diameter of the moon, can’t I just assign that value to a variable and just make sure I never change it?

One advantage of constants is they help prevent you from changing the value of a variable by mistake. It’s easy, especially in a big program with lots of code, to forget what you’re using a variable for, and make that mistake. By using a constant, you’re saying to yourself (as well as to anyone else who might be working on the code with you): This is a value that shouldn’t change. You can think of using a constant as a form of documentation, as well as a way to prevent mistakes.

Another advantage of using constants is that when your program is compiled, it can be optimized so that the constants are replaced with values, making your code just a tiny bit more efficient. Here’s an example:

> const num1 = 10;
undefined
> const num2 = 20;
undefined

> function area(radius) {
   return Math.PI * radius * radius;
}
undefined

> const circleArea = area(num1 + num2);
undefined

> circleArea
2827.4333882308138

In this example, the compiler could go ahead and compute the sum of num1 and num2 (30) when the code is being optimized, making the code faster when it’s actually run. A really good compiler could even recognize that calling the function area on a constant value will return the same value every time, and go ahead and assign the value 2827.4333882308138 to circleArea so the function
area is never even called at runtime. The reason the compiler can do this optimization is because num1 and num2 are constants: those values will never change, so num1 + num2 will always be 30, and, in the example above, the value of circleArea will always be equal to 2827.4333882308138. Anywhere the compiler sees an expression using num1 and num2, like num1 + num2, it can replace that expression with 30.

You might think of JavaScript as a scripting language that is interpreted rather than compiled (meaning, the browser executes the program as it reads the program, rather than first processing the code and turning it into an optimized form of code, as with other languages like Java, C#, C++, Objective-C, and Swift). But these days, JavaScript programs are not just interpreted; they are first optimized by the JavaScript engines that run in browsers. Instead of simply interpreting JavaScript code, browsers are first optimizing that code and then interpreting it, making your code run a lot faster.

Now you have a couple of good reasons to use constants in the future, when they’re widely supported by browsers, which will come with the adoption of the ECMAScript 6 specification by browser makers. However, as you can see, implementation of const is not yet consistent, and is only available in the most recent versions of some browsers. So it’s best not to use const in JavaScript you’re deploying on a web site for a while yet.

Resources

Don't miss out!!

Don't miss out on brain-friendly WickedlySmart updates early access to books and general cool stuff! Just give us your email and we'll send you something about once a week. 

You have Successfully Subscribed!