In this video you’ll learn two new ways to create variables in ES6 (ES2015). They are const and let. To better do that, we’ll compare var with let and const by diving into function vs block scope, variable hoisting, and immutability.
ES2015 introduces two new ways to create variables, let and const. As you probably know by now if you’ve watched any of my videos I don’t really like to make assumptions as to what you know. With that said, before we start talking about the difference between var, let, and const, there are three things we need to talk about first. They are variable declarations vs initialization. Scope, specifically function scope, and hoisting. Now I realize you might already know those three things so if you do, feel free to fast forward. But for now, let’s talk about variable declarations vs initializations.
Now that we know everything there is to know about var, let’s finally talk about the whole point of why you’re here. How does var, compare to let or const? First, let’s compare var and let. The main difference between var and let is that instead of being function scoped, let is block scoped. What that means is that a variable created with the let keyword is available inside the block that it was created in as well as any nested blocks. When I say “blocks, I mean anything surrounded by a curly brace like in a for loop or an if statement. So now looking back to our discountPrices function one last time. You’ll remember that when we console.log these variables, what we got were 3, 150, and 150. That’s because we declared the variables with the var keyword which meant that they were function scoped. Meaning, they were able to be accessed inside of this function. But now what happens, is let’s come in here and let’s change all of them to let. And I will copy. Now when we go to run this, what’s going to happen, is you’ll notice that we get a reference error. i is not defined. So right here we are trying to access i but, because we declared i with the let keyword, instead of var, that means i is only scoped to this specific block right here. To show you this, let’s go ahead and change this to var. Now if I run this, you’ll notice I get discountedPrice is not defined because again discountedPrice was declared with the let keyword, which means it’s only accessible in this block right here. The next difference has to do with hoisting.
As we saw with var, referencing a variable before the variable is declared will give you a value of undefined. This isn’t very intuitive, as we probably shouldn’t be referencing variable before they’re declared anyway. Luckily for us, let fixes this. Variable declared with the let keyword, will hoist the variable declaration to the top of the block just like with var, but, referencing the variable before the declaration will result in a reference error. To see this in action, let’s revisit our hoisting example we saw earlier with var. Even though we’re logging the hoisted variable before the variable is declared, because of hoisting, the interpreter will modify our code to look like this. So when the hoisted variable is logged, we get undefined. However, with let, the interpreter will still hoist the variable declaration but unlike var, if you try to reference a variable before the declaration, you’ll get a reference error.
So to recap so far, unlike var, variables declared with let will be block scoped and, trying to reference them before they’re declared will throw a reference error. Now that we understand the difference between var and let, what about const? Turns out, const is almost exactly the same as let. The only difference is that once you’ve assigned a value to a variable using const, you can’t reassign it to a new value. Let’s dive a little bit deeper into const because there are some common misconceptions.
We’re going to make two variables. The first one we’ll call name, and we will use the let keyword. The second we will use const and we will call it handle. Both of them will be strings. Now, if I wanted to reassign a new value to name, I can do that just by like you’re used to, saying name = ‘Tyler McGinnis’. But, if I try to reassign a new value to handle, what’s going to happen is we’ll get this error right here saying “uncaught type error: Assignment to constant variable”. So with const, once you’ve assigned a variable a value, you can’t reassign it a new value. Notice I’m being pretty clear with my words when it comes to const. We can’t reassign a new value to const. This is where it gets a little bit tricky. Say we had a person object that we declared with the const keyword. We’ll just give it a name property. Notice, what I can do, I can come in here and say person.name = ‘Tyler’. Because what I’m not doing, is I’m not reassigning person a new value. Instead, I’m just modifying an existing property on the person object. So if we look at our person object now, instead of being “Tyler McGinnis”, it’s just “Tyler”. But what I can’t do, is I can’t come in here and say person now equals a new object, because, since we declared it with the const keyword, we can’t reassign it a new value. So that’s why you need to be careful with const because const variable aren’t immutable. You can still change them. They just can’t be reassigned a new value.
Now the last question we need to answer, is which one should we use. The popular opinion, and the opinion that I subscribe to is that you shouldn’t always use const unless the variable is going to change. The reason for this is by using const, you’re telling your future self as well as any other future developers that use your code that this variable shouldn’t change. If it does change, you should use let, like in a for loop. So between variables that change change and variables that don’t change, there’s really no other use cases so that means we really never need to use var again. Now the unpopular opinion, though it still has some validity to it, is that you should never use const, because, when you use const, what you’re trying to do is you’re trying to say “this variable will never change”. Unfortunately, if that variable is an object as we saw earlier, it can still change.
So to recap, var is function scoped and if you try to use a variable declared with var before the actual declaration, you’ll just get undefined. const and let are blocked scoped and if you try to use a const or let variable before the declaration you’ll get a reference error. And the difference between let and const is that once you’ve assigned a value to const, you can’t reassign it, but with let, you can.