Learning JS? Topic: Hoisting

Learning JS? Topic: Hoisting

Subscribe to my newsletter and never miss my upcoming articles

Quiz time! Check if you understand hoisitng by picking the right answers to the questions below.

  1. console.log(myPage);
    var myPage = "mycodinghabits"
    
  2. let i = 5; 
    for( let i = 0; i < 10; i++ ){
     // Do stuff here
    }
    console.log(i);
    
  3. var x = 10;
    {
     var x = 2;
    }
    console.log(x);
    

If your answers were not

  1. undefined
  2. 5
  3. 2

Then maybe you should spend some time reading this post to understand why or bookmark it and come back later. However, before we define what hoisting is, we need to first understand what Global, Function/Local and Block scope is.

When the ES6 version of Javascript was introduced it came with two new key words which are let and const. With the introduction of these Javascript keywords came the concept of Block Scope. Before this Javascript variable declarations have only been working with what is called Global and Function Scope.

To clarify the difference we do this by thinking about where variables and functions can be declared and accessed in our code.

Global Scope

When variables are declared in a Global Scope it means that the variable was written outside functions or curly braces. And therefore can be accessed anywhere in that script file.

//Inside my script.js file the below code is written
var carName = "Range Rover";

//code here can use the variable carName

function getCarName(){
    //code here can also use carName
}

Function/Local Scope

With Function/Local scope when variables are declared in this scope it means that the variables are written inside a function and can only be accessed inside that function.

// code here can not use carName 

function getCarName(){
    var carName = "Range Rover";
    //code here can use carName
}

// code here can not use carName

Block Scope

Block Scope which is new with JavaScript ES6 only applies to the let and const keyword. This means that variables declared/written with the let/const key word inside curly braces can only be accessed inside those braces and not outside of it.

{
    let x = 10;
}

// x can NOT be used here

This does not apply to the var keyword

{
    var x = 10
}

// x can be accessed here.

TL;DR - In summary

Global scope refers to any area in script file that variables and functions have been declared (written). These variables and functions declared in this scope can be accessed anywhere.

Local/Function scope refers to the area within a function. Variables declared here can only be accessed inside this scope and not outside of it.

Block scope refers to the area between two curly braces { }. Block scope only applies to let and const, which means variables declared with let and const inside a block scope cannot be accessed outside of this scope. This rule doesn't apply when you are using the var keyword. Using the var keyword allows the variable to be accessible outside of the block scope.

Noteworthy

In a Javascript file the global scope is the JavaScript environment, however when writing JavaScript for HTML, the global scope is the window object.

Global variables defined with the var keyword belong to the window object therefore the code below is valid

var nameOfPage = "mycodinghabits"; 
// code here CAN use window.nameOfPage

However, if you use the let keyword to define a variable then it would not belong to the window object.

let nameOfPage = "mycodinghabits"; 
// code here CANNOT use window.nameOfPage

Hoisting

Now that we have a good understanding of the different scopes, lets take a look at Hoisting. This term came about because of the way the JavaScript complier interprets the code you write. When you use the key word var to declare a variable it is taken to the top of the scope (this could be a global, block or function scope), this allows for the variable to be initialised anywhere in that scope and still be valid. If that is true the code below is correct.

carName = "Range Rover";
console.log(carName);
var carName;

//The code above is valid because what the Javascript complier reads is this 

var carName; 
carName = "Range Rover";
console.log(carName);

Function declarations are also hoisted.

function hey() {
        console.log('Say Hi to ' + myPage);
};
hey();
var myPage = 'mycodinghabits';

//This is how the JavaScript complier reads this

function hey() {
        console.log('Say Hi to ' + myPage);
};
var myPage;
hey();
myPage = 'mycodinghabits';

//The console log will print "Say Hi to undefined" because the myPage variable 
//is not yet aware of the value assigned.

Hoisting is JavaScript's default behaviour of moving declarations to the top of its current scope.

Noteworthy

The let and const keyword are not hoisted - If you try the same code above with these keywords you will get a reference error.

JavaScript only hoists declarations, not initialisations.

var x = 10; // Initialize x
var y;     // Declare y

let add = x + y;
console.log(add);

y = 2;    // Assign 2 to y

If you run the code in an editor, the value of add will be NaN which means Not a Number. This is because only Javascript declarations are hoisted and not the initialization. So in this case the complier read the code like this.

var x; 
var y; 
x = 10; 

let add = 10 + undefined;
console.log(NaN);

y = 2;

JavaScript Good Practice

Inorder to avoid bugs due to the JavaScript behaiviour it is good practice to declare and initialise all your variables at the top of the scope it will be used. Many Developers tend to adopt this approach.

But according to the Airbnb Javascript style guide it is recommended to declare your variables using the let and const keywords to avoid polluting the global scope. This approach is even particularly useful because using the let and const keyword forces the variables to be initialised before being used.

If you found this article useful please react to it so other developers can see it, leave a comment if you have any questions and stay tuned for other articles in this series

 
Share this
Proudly part of