JavaScript Variable and Function Block Scope

In this article, you’ll learn about how variable and block scope in JavaScript has changed with the introduction of ES6.

Imagine you have a simple function that logs at the numbers from one to ten:

function countToTen() {
    for (var i=1; i<=10; i++) {
        console.log(i);
    }
}

The variable that we’ve defined inside the for loop, i, is actually accessible outside of the for loop scope i.e. the curly braces {}.

This is actually normal JavaScript scope behaviour and it’s what we should expect if we’re using the var keyword to declare variables.

ES6 Variable Block Scope

So this is where ES6 variable block scope comes in. If we change the var keyword to let we get an error.

function countToTen() {
    for (let i=1; i<=10; i++) {
        console.log(i);
    }
    console.log(i); // ReferenceError: i is not defined
}

You will see if you try and run the code that you can no longer access i as it’s scope is restricted to the for loop only.

So we looked at constants in a previous lesson and where a constant cannot be used, i.e. you really need to re-assign a value to the variable at some point in your code, then you should use the let keyword. The var keyword is pretty much obsolete now.

ES6 Function Scope

Let’s take a look at our countToTen function again.

function countToTen() {
    function multiply(n) {
        return n * 2;
    }

    for (let i=1; i<=10; i++) {
        console.log(multiply(i));
    }
}

This time however, there is an inner function defined which is used to multiple the output in the for loop.

This again is totally fine, we can declare a function inside a function and it’s scope is anywhere in the parent function i.e. it can be used anywhere inside the function.

But just to make things really crazy, we could define another function inside the for loop which will be purely scoped to within the block of the for loop.

function countToTen() {
    function multiply(n) {
        return n * 2;
    }

    for (let i=1; i<=10; i++) {
        function multiply(n) {
            return n * 5;
        }
        console.log(multiply(i)); // Uses for loop multiply function
    }

    console.log(multiply(10)); // Uses inner countToTen function
}

This allows us to create functions with the same name at different levels of a block’s scope and then modify the behaviour of those functions depending on where they are called.

Learn about Variable and Function Block Scope on the Junior Developer Central YouTube Channel.