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:
-
The block scope, where for example a variable is only visible inside an if condition or a for loop, when this variable is declared inside this condition. C# uses this type of scope.
-
The function scope, where a variable is visible and can be used inside the whole function. The variable remains visible only inside the function and not outside of it.
JavaScript uses a functional scope. Let’s see with a code example how this apply:
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:
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:
- JavaScript searches for a surname variable inside the innerTestingScope function. No such variable is found.
- JavaScript searches for a surname variable inside the testingScope function. The variable is found and it contains the value Christos. This will be the case even when the innerTestingScope function was declared before the assignment of the value Christos in the surname variable.
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:
- JavaScript searches for a surname variable inside the testingScope function. No surname variable is found.
- JavaScript searches for a surname variable in the global object. No surname variable is found there and the engine throws a ReferenceError: Can’t find variable: surname exception.
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.