Lesson Tuesday

One of the biggest and most popular changes in ES6 is the addition of the let and const keywords, which replace var. From here on out, we’ll use let and const instead of var in our code.

You may be wondering why we teach var at all if there’s a new and improved way of declaring variables. The var keyword is so ubiquitous in the JavaScript world that it’s an important part of any new coder’s initiation into the language. When you’re looking at documentation and legacy code, you’ll often see var in use. You may even find yourself developing in an environment where code isn’t transpiled, which means you won’t be able to use let and const. However, let and const represent a significant improvement over var and they will eventually replace var completely.

let and const

First, what’s the difference between let and const?

We should use let when we want to declare a variable that changes. const, on the other hand, is short for constant, which means we’ll use it for variables that won’t change. For instance, the freezing point of water is 32 degrees F. In an application, that could be represented as const freezingTemp = 32. However, the current temperature is always changing, so we’d represent the currentTemp variable with let.

let and const make our code more expressive. A developer could look at variables in our code and immediately get a sense of whether they’re supposed to change or not. This isn’t possible with var.

Lexical Scoping

There’s another key difference between let, const and var, and it has to do with scoping. Unlike var, let and const both use lexical scoping. Lexical scoping means a variable can only be called in the block where it’s defined. A few examples should make this clear. Try the following in the console:

function scopeCheck() {
  if (true) {
    let x = 5;
  }
  console.log(x);
}

If you call scopeCheck(), you’ll get the following error: Uncaught ReferenceError: x is not defined. This is because x is lexically scoped to the block it’s in, which is if (true) { }. (A quick note: if you have any confusion regarding blocks, a block begins and ends with curly braces. There are two blocks in the code above: an outer scopeCheck() function and an inner conditional block.)

Try changing let in the code above to var and you’ll see that scopeCheck() logs the value of x. This happens because var is scoped to the function it’s contained in, not the block. (If var isn’t inside a function, then it will have global scope.)

The difference in scope is subtle but important. As developers, we should always try to keep our code as tightly scoped as possible. Otherwise, our code can have unintended side effects. let gives us more fine-grained control over variable scope. If we do want let to be scoped like var, we can easily do that. We just need to scope let to the function instead of the inner block, like this:

function scopeCheck() {
  let x = 5;
  if (true) {
    x = 6;
  }
  console.log(x);
}

Now x is scoped to the function and is accessible in the inner block of the function (where it is modified).

Using const

const is lexically scoped like let. But const also has another interesting and useful feature. Once we assign const to a variable, we can’t assign a new value to it. You can test this in the console. Try this:

const number = 5;
number = 6;

You’ll get the following error: Uncaught TypeError: Assignment to constant variable.

However, be careful. Just because we can’t assign a new value to a constant doesn’t mean we can’t modify it. Here’s an example:

const array = [ 5,6,7 ];
array.push(8);

If you check the value of the array in the console, it’s now [5,6,7,8].

Just to clarify further, even though we can modify the contents of this array, we still can’t assign a new array to it. So if we were to try to assign a new array to the array variable like this: array = [5,6,7,8,9], we’ll get a TypeError again.

To recap, let and const make your code more expressive than var. Both are lexically scoped, which is a subtle but significant improvement over var. The value of a constant can’t be reassigned, but constants can potentially be modified. From now on, you should use let and const instead of var in your code.