JavaScript: Variable Hoisting

On our basic concepts of JavaScript series of posts, let's take a look at Variable Hoisting.

JavaScript moves variables and functions declaration to the top of its scope during execution. This behaviour in JavaScript is called Hoisting. Let's see that with a code example,

console.log(foo); // Output: undefined
var foo = "hello world";
Variable Hoisting Example

In any other programming languages, the expected output for the above code would be some sort of "foo not declared error". But in JavaScript, it is already declared with the type of undefined. This is because JavaScript interprets the above code like,

var foo;
console.log(foo); // Output: undefined
foo = "hello world";
Interpretation of Variable Hoisting by JavaScript

It takes all var declaration to the top of its scope and this is called variable hoisting.

Why we should learn Hoisting?

Because it will create a lot of unexpected behaviour during execution. On my previous posts, we looked into Closures and how they create a local scope whenever you declare a function. Let's take a look at this example to see how Hoisting breaks that rule when you don't declare the variable with var keyword,

function foo() {
    bar = "Hello world";
    var baz = "I'm new to coding";
}
foo();
console.log(bar); //Output: Hello world
console.log(baz); //Reference Error: baz is not defined
Breaking Closure without var keyword

notice we haven't used var keyword in front of declaration bar. JavaScript first looks for its variable declaration on its local scope. If it can't find a local declaration, it goes up one level in scope and looks for bar declaration. On the above example, one level up to foo() scope is global scope. If it can't find in its parent scope it automatically declares your variable with var keyword like,

var bar;
function foo() {
    bar = "Hello world";
    var baz = "I'm new to coding";
}
foo();
console.log(bar); //Output: Hello world
console.log(baz); //Reference Error: baz is not defined
Interpretation of variable hoisting on a scope

and no matter how deep the foo function scope is, JavaScript will keep looking at its parent scopes till it finds or declares bar variable.

ES6 Declarations

What happens to let and const keywords of ES6? Do they get hoisted? For that let's see what they output if you just declare them and don't assign a value same like what the var variables gets hoisted.

let foo;

console.log(foo); Output: undefined

const bar; //Syntax error: missing initializer in const declaration
ES6 let keyword hoisting

so let's see if JavaScript hoist let and const

console.log(foo); //Output: undefined
let foo = "Hello world";

console.log(bar); //ReferanceError: cannot access bar before initialization
const bar = 200;
ES6 let and const keyword hoisting

the fact that both the variables are available to console.log proves that they too get hoisted. But in the case of const, it is different. Declaring const bar; without assignment produces SyntaxError, because of this JavaScript hoist them but doesn't allow you to access the const variable before its initialization. So yes, they too gets hoisted.

To keep the post small and concise, I am splitting variable and function hoisting into two posts.