Learning ES6 - let and const

4 min read.

Over the past few weeks I’ve started to dive more into EcmaScript 6. I’ve decided that I’m going to take the time and document what I learn here, starting with the new ways of declaring variables let and const.

I’ve also started a new repository over at Github that will act as a cheat sheet. Of course, as of writing this, it is still a work in progress but I’m hoping to expand it further over the next coming weeks.

let

To explain the new ways of defining variables one must first explain a bit about how defining variable works today with EcmaScript 5. In ES5, the only way to define variable is to use the var statement. When defining a variable using var the variable becomes assigned to the scope of the function that it declared in. This means that if you were to declare a variable using var in an if-else block, the variable would not be constrained to that block but the surrounding function.

var foo = 'foo'; // => assigned to the global object scope.

function bar() {
	var bar = 'bar'; // => assigned to the scope of bar().

    if(true) {
    	var baz = 'baz'; // => also assigned to the scope of bar().
    }

    console.log(baz); // => returns 'baz'.
}

This is called hoisting. the JavaScript engine interprets the above code as follows

var foo = 'foo';

function bar() {
	var bar = 'bar';
    var baz = undefined; // => the engine declares any var as undefined at the top.

    if(true) {
    	baz = 'baz';
    }

    console.log(baz);
}

This feature can sometimes be useful but at the same time, if you don’t know what you are doing, it can also create some annoying bugs. This is were let comes into play. Using let in ES6 will be a safer way to declare variables and, in most cases, should be the only way to declare variables further on.

Variables declared with let will instead be assigned to the code block it was declared in. Also, declaring it globally will not assign it to the global object, but to the global block. If we rewrite the previous example using let it would look something like this

let foo = 'foo';
console.log(window.foo); // => undefined, foo is defined on the global block instead.

function bar() {
	let bar = 'bar';

    if(true) {
    	let baz = 'baz';
    }

    console.log(baz) // => ReferenceError.
}

As stated before, variables declared globally with let will not assign the variable to the global object, in this case window. Also, A ReferenceError occurs because baz is assigned to the if-else block and variables declared using let can’t be used before it is declared. Declaring a variable more than once will also produce an error

let x = 5;
...
let x = 1; // => SyntaxError.

let in loops

if-else blocks are not the only place where let declarations are useful. An even better place is in for and while loops. Using let in conjunction with a loop will contain any variables within each iteration and not leak any variable state after the loop is finished.

var numbers = ['one', 'two', 'three'];

for (var number of numbers) {
	console.log(number); // => 'one', 'two', 'three'
}

console.log(number); // => 'three'

declaring number by using let instead will not leak

var numbers = ['one', 'two', 'three'];

for (let number of numbers) {
	console.log(number); // => 'one', 'two', 'three'
}

console.log(number); // => ReferenceError.

Also, because each let declaration in a loop counts as it’s own instance, it would be treated as separate values if it would be used in some sort of callback function, like setTimeout.

var numbers = ['one', 'two', 'three'];

for (var number of numbers) {
	setTimeout(function(){
    	console.log(number); // => 'three' three times.
    }, 1000);
}

if let would be used in the code above, it would output one, two , three instead.

const

Declaring constants are not so different from declaring variables using let. There are only two things that are different.

  1. A value must be assigned when declaring a const.
  2. A const can only be assigned a value once.
const FOO; // => SyntaxError.

const BAR = 'my const';
const BAR = 'my new const'; // => SyntaxError.

That is pretty much all. As I said in the beginning of this post, I’ll continue to post more about my experience with learning EcmaScript 6 and if you liked this post you can follow me on Twitter to stay updated. In the meanwhile, checkout the cheat sheet I’ve started working on, all feedback and contributions are appreciated!

comments powered by Disqus