Javascript scope and hoisting: Understanding block scope

Understanding our favourite “var, let and const”

Every programming language has its own rules regarding the scope of the data being stored during program execution. The term Scope refers to space in the program where the data can be accessed. Traditionally Javascript only had two types of scopes: Global and Function scope. With the introduction of ES6, Javascript is introduced with the third type of scope — Block scope.

Hoisting is a feature unique to Javascript. Hoisting in javascript refers to the variable and function declaration being moved up to the top of the scope.

Image for post


In this article, we will understand the meaning scope in javascript, the implications of ES6 (block scoping), and the effects of hoisting.

Javascript mainly has two types of scope: Global and Function scope.

Global scope refers to all the variables declared in a JS file that are not inside any function. These variables have access anywhere in the file. Function scope refers to a limited private scope that the variable gets within the function it is declared. This variable can be accessed anywhere within the function, but not outside it. Let us try to illustrate with an example. Consider the following lines of code:

In the above code, globalVariable exists throughout the JS file. Hence, it can be accessed anywhere. Since javascript code mostly executes in the browser, it is good to know what global scope means in the context of a browser. In any web browser, the global scope is created for us, and the window object lies in the global scope. Hence in the browser, the globalVariable can be accessed either directly or through the window object window.globalVariable. Since in web development we might have several javascript files, it is important to know that all the variables declared with the global scope in these files are available in the window object. This is an important point to note, if multiple files contain the same variable name declared in the global scope, unexpected code behaviors might arise because the same variable might get overridden in different files.

The variable1 exists only inside the function func1, and it can be accessed only inside this function. The global space and func2 do not have access to this variable. The console.log statements in both places will throw an error.

Consider the next piece of code:

The above code might confuse those not familiar with javascript. innerVariable is in the scope of innerFunc, however, outerVariable and globalVariable are also accessible here. This is because, javascript first checks for the existence of a variable within the current scope, if the variable is not present, it looks up for the variable in its immediate parent scope, and so on until the global scope is reached. If the variable is not present anywhere during this lookup, javascript throws Reference error.

The set of nested scopes forming a scope ladder is called Scope Chain, and this process of checking for a variable through the scope chain in ascending order is called Variable lookup. Note that the variable lookup is unidirectional, and happens only from one scope to its parent scope.

ES6 introduced two new ways of holding data in the application. let and const. These are two additional ways to declare and use data in the JS program. let is quite similar to var. Using let we can declare and use variables anywhere in the program just like var. The value assigned to the variable can also be changed whenever we want as long as the scope of the variable remains valid.

const is used to define a value, however, this value doesn't change throughout the execution. The values assigned with the const keyword cannot be changed, any attempt made to change this will result in an error. It is also the reason why const must be assigned a value during the declaration phase itself.

Note that, even if arrays and objects are declared with const, their inner values can be changed.

With the advent of ES6, javascript was introduced with a new type of scope, let and const allows us to declare and use the variables with block scope. Block scope means that any variable declared within a pair of brackets {} can only be used within those brackets. This also means that the variables declared within if-else blocks, for loop blocks will all have block scoping when they are declared with let or const. It is important to note, however, that ES6 still doesn't give block scoping capabilities. Since let provides block scoping which is more in line with other object-oriented programming languages, it is preferred over the usage of var Consider the following lines of code:

Variable hoisting is important to understand certain unexpected behavior codes have in javascript. All data values declared/defined using var, let, const, and the functions are hoisted in javascript. This means that the declaration is moved up its scope. Javascript is executed in two phases: The Parse phase and the Execution phase. During the parsing phase, memory allocation, scope creation, and hoisting are carried out. Consider the following example:

The javascript code translates this piece of code to:

However, there is a small catch in variable hoisting. During variable hoisting, the variable declared with var is assigned undefined value. However, those declared with const and let are not assigned anything. This leads to the creation of the Temporal Dead Zone. Because of this, even if the variable declared var is used before its declaration, the code doesn't throw any error. However, if the variable declared using let or const is used before they are declared, we get an error.

So far we know that var allows function scoping and let allows block scoping. However, there is another difference between the two. If closure is created within the loop, variables declared using let will be bound to the value during the current iteration of the loop, whereas the value of var variables will be the current value of the variable. Consider the following example:

The for loop created using var will print the number 10, ten times. This is because 10 is the final current value of i. However, the for loop containing let will print the numbers from 0 to 9, this is because the value of let is preserved and is bound to the current iteration value. This is an important concept that will be helpful when dealing with asynchronous functions within the loops.

Variable scope and hoisting are the basic concepts of javascript which help us in building applications. Note that with the addition of let and const we have only introduced the possibility of having a block scope in javascript. The global and function scope always remains whether we use var, let, or const. I hope that this article helped you understand the usage of var, let and const at a much deeper level.

Originally published at

Written by


Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store