Variable & Function Hoisting

During compilation JavaScript variable and function declarations are moved around their containing scope. This behaviour is called Hoisting, you may not even notice that it is happening but it is an important concept to be aware of.

So code that is written like;

fnName(); //1234
function fnName() {
    return 1234;
};

Will actually be executed like;

function fnName() { // Function Declaration: is hoisted
    return 1234;
}; 
fnName(); //1234

Although it is not a good idea to structure your code in this way, Hoisting moved the function declaration to the top and allowed the function to be called before it was defined in the program flow.

Only declarations are hoisted, expression assignments are not hoisted. Consider the below example.

console.log(aString);
console.log(aNumber);
console.log(aFunction());

var aString = 'A string'
var aNumber = 123;
var aFunction = function(){
    return 0.123;
};

The example would be execute as;

var aString; // Declaration: is hoisted
var aNumber; // Declaration: is hoisted
var aFunction; // Declaration: is hoisted

console.log(aString); // undefined
console.log(aNumber); // undefined
console.log(aFunction); // aFunction is not a function

aString = 'A string'; // Assignment: not hoisted
aNumber = 123; // Assignment: not hoisted
aFunction = function(){ return 0.123; }; // Assignment: not hoisted

As you can see, the variables themselves are defined because their declarations were hoisted, although they have an undefined value because their assignments were not hoisted.

If the variables were not defined an error would be thrown rather than just returning an undefined value, try running the below line of code.

console.log('aNonExisitantVariable'); // Uncaught ReferenceError

JavaScript tries to find a variable by the name “aNonExisitantVariable”, though as it has not been declared the Uncaught ReferenceError: aNonExisitantVariable is not defined error is thrown.

Hoisting and Variable Scope

If your code is scoped behind a closure it will only be hoisted to the top of that closures scope.

console.log(aString);
var aString = 'A string';
var fn = function() {
    console.log(scopedString);
    console.log(scopedNumber);

    var scopedString = 'A scoped string';
    var scopedNumber = 123456;
};

The example would execute as;

var aString; // Declaration: is hoisted
console.log(aString); // undefined
aString = 'A string'; // Assignment: not hoisted
var fn = function() {
    var scopedString; // Declaration: is hoisted to top of closure
    var scopedNumber; // Declaration: is hoisted to top of closure        
    console.log(scopedString); // undefined
    console.log(scopedNumber); // undefined

    scopedString = 'A scoped string'; // Assignment: not hoisted
    scopedNumber = 123456; // Assignment: not hoisted
};

Did you find the article helpful?
Show your ❤ with the click of a button, then tell all your friends.

(If you have liked this article before but find yourself coming back for reference please throw a ❤ my way each time you return and find it of help.)

What do you reckon?

Your email address will not be published. Required fields are marked*

*

!

An error has occured with your submition. Sorry there is no further details, if the problem persists please use the contact form to inform us.