Variable Scope - Must Know JavaScript features every programmer should learn to master the language

JavaScript is a small language, however, as any other technology one should invest some time in learning the fundamentals of it, so that she has a solid knowledge when writing code or architecting web applications.

With the Must Know JavaScript features articles I try to give you a starting point for your further familiarization with the most important features of the language. You are going to use these features extensively as a JavaScript engineer, directly or indirectly.

Let’s talk about scope

In general, the scope in a programming language affects the visibility of fields/ properties in a class/ module or of the arguments passed or the variables declared inside a function. There are two main categories of scope in the modern languages:

JavaScript uses a functional scope. Let’s see with a code example how this apply:

1
2
3
4
5
6
7
8
9
10
    function testingScope(isSurname) {
        var surname = "";

        if (isSurname) {
            surname = "Christos";
            console.log(surname);
        }
    }

    testingScope(true);

The console.log will log the name Christos since JavaScript has functional scope and the surname variable is visible in the whole testingScope function block and not only inside the if clause.

The following code is also perfectly legal in JavaScript:

1
2
3
4
5
6
7
8
9
10
    function testingScope(isSurname) {
        surname = "";

        if (isSurname) {
            var name = "Christos";
            console.log(surname);
        }
    }

    testingScope(true);

In this case, we are assigning an empty string to a variable which is declared afterwards (inside the if clause). This code will also log Christos in the console. This behavior of variables in JavaScript is called Hoisting and we are going to discuss about it in an upcoming article.

The scope chain and how it works

Let’s take a look at the following code example which also logs Christos. As you can see the inner innerTestingScope function has access to the properties/ variables of the outer testingScope function. This is the scope-chain feature and the rule tells us the following:

The scope can be nested. If a variable cannot be found in the immediate scope (scope of the current function), then JavaScript looks at the next outer scope to find the variable and if no match was found the search continues all the way up to the scope-chain till the global scope was reached.

If the variable is not found in the global object, then a ReferenceError exception is thrown.

The feature of variables inside functions being accessible from variables inside nested functions is a great way to create private properties in JavaScript. This is the so called module pattern, which is going to be covered with an upcoming article.

So in the following example the scope chain will perform the following operations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    function testingScope(isSurname) {
        var surname = "";

        function innerTestingScope() {
            console.log(surname);
        }

        if (isSurname) {
            var surname = "Christos";
            innerTestingScope(surname);
        }
    }

    testingScope(true);

The following code sample will log nothing on the console, since the testingScope function tries to access a variable defined in an inner function. The scope chain works from bottom to top and not the other way around.

The scope chain will perform the following operations:

1
2
3
4
5
6
7
8
9
10
11
    function testingScope(isSurname) {
        function innerTestingScope() {
            var surname = "Christos";
        }

        if (isSurname) {
            console.log(surname);
        }
    }

    testingScope(true);

Conslusion

What you have to take away from this article is that JavaScript uses a functional scope, a feature that gives us great power when we want to affect the visibility of a variable. Great responsibility have to be paid to this feature if we want to avoid unexpected not found exceptions.

comments powered by Disqus