JavaScript
Article
By Aurelio De Rosa

Preparing for ECMAScript 6: let and const

By Aurelio De Rosa

If you’re a frequent SitePoint reader, especially of the JavaScript channel you’ve hopefully learned a lot about the new features of ECMAScript 6 lately. So far I’ve written articles about Map and WeakMap, Set and WeakSet, new methods available for String, Number, and Array, and new syntax available for functions.

In this tutorial I’ll introduce you to two new keywords: let and const. They enhance JavaScript even more by filling the gap with other languages and providing us a way to define block-scope variables and constants. If you want to learn more about them, keep reading.

let

Up to ECMAScript 5, JavaScript had only two types of scope, function scope and global scope. This causes a lot of frustration and unexpected behaviors to most developers coming from other languages such as C, C++, or Java. The reason is that JavaScript lacks block scope, which means a variable exists, and thus is only accessible, within the block in which it’s defined. A block is everything inside an opening and closing curly bracket. Let’s take a look at the following example:

function foo() {
   var par = 1;
   if (par >= 0) {
      var bar = 2;
      console.log(par); // prints 1
      console.log(bar); // prints 2
   }
   console.log(par); // prints 1
   console.log(bar); // prints 2
}
foo();

After running this code, you’ll see on the console the following output:

1
2
1
2

What most developers coming from cited languages would expect is that outside the if block you can’t access the bar variable. For example, running the equivalent code in C results in the error 'bar' undeclared at line ... which refers to the use of bar outside the if.

With ECMAScript 6 the situation will change with the availability of block scope. The ECMA organization members knew that they could not change the behavior of the keyword var for the sake of backward compatibility. So, they decided to introduce a new keyword called let. The latter can be used to define variables limiting their scope to the block in which they are declared. In addition, unlike var, variables declared using let aren’t hoisted. If you reference a variable in a block before the let declaration for that variable is encountered, this results in a ReferenceError. But what does this mean in practice? Is it only good for newbies? Not at all!

To explain you why you’ll love let consider the following code taken from my article 5 More JavaScript Interview Exercises:

var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
   nodes[i].addEventListener('click', function() {
      console.log('You clicked element #' + i);
   });
}

Here you can recognize a well-known issue that comes from variable declaration, their scope, and event handlers. If you don’t know what I’m talking about, go check the article I mentioned and than come back, I’ll wait here.

Back? Good! Thanks to let we can easily solve this issue by simply reassigning the value of i to a support variable declared using let:

var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
   let j = i;
   nodes[i].addEventListener('click', function() {
      console.log('You clicked element #' + j);
   });
}

Cool, isn’t it?

Now the bad news. At the time of writing no browsers support this feature by default, which means that this isn’t really something you can use today unless you use a transpiler that will convert your code into an equivalent source that is compatible with ECMAScript 5. In Chrome 38 and Opera 25, you can try let by activating the “Experimental JavaScript features” flag but only if you run the code in strict mode. Please note that even if a given browser supports let behind a flag, it might implement only a subset of the specifications. For example, the browser might not be able to throw the ReferenceError where needed.

A live demo that shows the difference between var and let is shown below and also available as a JSFiddle:

const

const addresses the common need of developers to associate a mnemonic name with a given value such that the value can’t be changed (or in simpler terms, define a constant). For example, if you’re working with math formulas, you may need to create a Math object. Inside this object you want to associate the values of π and e with a mnemonic name. const allows you to achieve this goal. Using it you can create a constant that can be global or local to the function in which it is declared.

Constants defined with const follow the same scope rules as variables but they can’t be redeclared. Constants also share a feature with variables declared using let in that they are block-scoped instead of function-scoped (and thus they are not hoisted). In case you try to access a constant before it’s declared you’ll receive a ReferenceError.

In this case too, the support is heavily fractional and most browsers have implemented a subset of the feature. In case you want to know in detail which browsers support const and which specific features are implemented, you can take a look at this ECMAScript 6 compatibility table.

An example of use of const is shown below:

'use strict';

function foo() {
   const con1 = 3.141;
   if (con1 > 3) {
      const con2 = 1.414;
      console.log(con1); // prints 3.141
      console.log(con2); // prints 1.414
   }
   console.log(con1); // prints 3.141
   try {
      console.log(con2);
   } catch(ex) {
      console.log('Cannot access con2 outside its block');
   }
}
foo();

A live demo of the previous code is shown below and also available as a JSFiddle. Remember that different browsers may behave differently based on the features supported.

Conclusion

In this tutorial I’ve introduced you to two new and very interesting features of JavaScript that are available in the upcoming ECMAScript “Harmony” 6. I bet that most of you have encountered use cases where the use of let and const would have been beneficial. Unfortunately, due to their poor support among browsers you have to use a transpiler or you won’t be able to take advantage of them. Hopefully this will change soon and, anyway, this is what the future of JavaScript looks like.

  • Whocares

    The “example of use of const” shows an example of “let”, not “const”.

  • Aurelio De Rosa

    Hi. We’ve already fixed the issue.

  • Lubos Turek

    Actually, variables declared with let/const are hoisted, but they stay uninitialized. It is pretty comlicated, here you can find detailed explanation: http://stackoverflow.com/q/31219420/3242070

    • Aurelio De Rosa

      You’re right. When I wrote the article my understanding of let and const was different.

  • ECMAScript 6: let and const

Recommended
Sponsors
Get the latest in JavaScript, once a week, for free.