Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Ecma 1
  • Overview
  • Transcript

2.1 A New Scope

ES6 brings a whole new scope to JavaScript block scope. Let’s take a look at how we can declare local block-scoped variables and functions. We can also take a quick look at the new const keyword.

Related Links

2.1 A New Scope

Hi folks. In this lesson let's start our tour of ES6 by looking at the new scope that has been introduced to JavaScript. I'm talking about block scope, of course. Until now JavaScript's function scope and variable hoisting has been the source of much confusion for newcomers to the language especially those coming to JavaScript from another language that already has block scope. A block in JavaScript is anything within the curly braces of a control flow structure like if, else or a while loop. We can create a variable that scopes to its containing block rather than its containing function by using the new let keyword to declare the variable rather than the var keyword. The behavior of var itself hasn't changed in any way. The best way to understand block scope is with an error, strangely enough. So let's open up our es6.js file. And let's add the following code to illustrate how block scope works. So we start out with a console.log, and we're going to log the contents of a variable called block. We then have a rather contrived if statement which just checks whether true is true, and if it is, which it will be, we declare the variable block using the new let keyword. And in this case the value of this variable is a simple string. The Chrome browser has actually implemented block scope. So we can run this file in Chrome directly without using Babel to transpile it down to ES5. To do this, we just need to update the script reference in the HTML page to point directly to the es6.js file instead of the generated es5.js file. So let's just do that quickly now. And now let's run our file in Chrome. When we open up the console, we see an uncaught reference error that the variable block is not defined. So if we'd have used the var keyword instead of the let keyword to define our block variable, that variable would've been hoisted to the top of its scope, which is the immediately invoked function. An so our code wouldn't throw an error but block would be undefined at the time when it's locked. That's the difference between let and var. Here let creates the block variable only in the scope within the curly braces of the if. And so we see this reference error. Even if we move the console log to after the if statement, we'll still see the same error because it's still outside of the if block. So the main feature of let is to create a variable scoped to its containing block. But there's another important difference between let and var. Variables declared with let are not hoisted to the top of their block scope. So if we move the console log into the if block but before where we declare the block variable, we'll still see the error. The fact that we still see an error in this case is down to a feature of ES6, and specifically the let keyword known as the temporal dead zone. Because let variables are not hoisted, they can't be used until after they've been declared. So everything inside the block prior to the declaration of the variable is known as the temporal dead zone because the variable is still not visible. We can learn something interesting about Babel here as well, actually. If we put the console log back outside of the if block. And now let's compile our ES6 file down to ES5 using Babel. So now let's take a look at the code that's been generated. So here we can see that Babel has actually detected that our code will throw an error. And it has renamed the block variable inside the block to _block. So that when we try to log the block variable, we'll still see the same error in our browser. And this is a great helpful debugging ES6 code. So in other regards, let is identical to var. We can use the comma operator to chain multiple declarations together in a single statement. And we need to just comment out that first console log. You could say that using let can help make our code more readable. Because of hoisting, we've become used to declaring all of our variables at the start of their containing function. But sometimes, especially when declaring index variables used within for loops, the usage of a variable can be a number of lines of code away from its declaration. And this can be confusing or less readable. In reality, a function shouldn't be so long that you forget which variables are available inside it, but even so, block scoping allows us to move the declaration of let nearer to its usage. Because let isn't hoisted, we don't need to declare it at the top of its scope so it's potentially more readable in situations like this. We could even have some other x defined in the scope outside of the for loop and that wouldn't be affected by or affect the version of x inside the loop. Aside from let, another way to create a block scope is with the const keyword, which creates a constant. A constant in JavaScript is a read-only variable whose value can not be changed through reassignment or through being redeclared. Here, the constant PI is declared and assigned a simple numeric value. A const can only be declared once and it must have a value assigned in the same expression in which it's declared. If we try to assign a value again, we'll see a type error. Like let variables, consts are not hoisted. There is one thing about consts that we should be aware of, their value is not immutable. It can't be changed by reassignment, but it can be changed by reference. If we set an object as the value of the const, we can still update the values of the object even though it's a constant. So let's run this code in our browser now. And we see that the test property of our constant object has been updated from test to changed. So in this way, we're able to change the reference object and therefore the constant, indirectly, just something to be aware of. So in this lesson we learned about JavaScript's new block scope. We saw that to create a new block scope, we need to use either the let or const keywords to specify a value. These types of values will only be visible to the block they are in, rather than the containing function scope as a standard variable would be. We saw that values defined using let or const are not hoisted, and we also learned that a constant's value cannot be changed by reassignment, but may be changed by reference. Thanks for watching.

Back to the top