How Does Function Hoisting Work in JavaScript?
Oct 11, 2016 • 3 Minute Read
Hoisting can be a tricky part of JavaScript to understand. This article will give a concise definition of hoisting and simple examples of it in action.
In JavaScript, the default action is for declarations to be moved to the top of the code. Declarations are moved to the top of the current scope by the JavaScript interpreter, meaning the top of the current function or scripts. All functions and variables are hoisted.
The best way to understand function hoisting is to first look into how variable hoisting works, the principles are similar and will give an understanding for functions. The following code will show the intended output of something with the declaration written afterwards.
console.log(laterDeclare);
var laterDeclare = "Define me later!"; // Output: Define me later!
JavasScript internally takes these variables that have been declared later on during the program and hoists them up to the top to be read first. The JavaScript interpreter is scouring through the entire program and puts these declarations first so that the prior code does not output an error. The equivalent code written like this is essentially what the JavaScript interpreter is reading.
var laterDeclare = "Define me later!";
console.log(laterDeclare);
// Output: Define me later!
The same idea can be applied to function hoisting, but with a bit of a twist and few subtle nuances.
Function Hoisting
Certain types of function declarations follow the same behavior as a variable does. This can be extremely helpful because it makes your code more streamlined and readable. It is useful because higher abstract level logic can be applied at the start of the source code. Take this simple function declaration as an example:
hoistFunc(); // "Functions hoist too!"
function hoistFunc() {
console.log("Functions hoist too!");
}
The JavaScript interpreter allows for a function declaration to be read like this. The difference comes when trying to do the same thing for a function expression. If you attempt to do that, you’ll run into an error.
// TypeError: Undefined
nonHoistedFunc();
var nonHoistedFunc = function () {
console.log("This will not work!");
};
The function will not be hoisted if it is part of the overall expression. Another aspect to take into account is the fact that initializations are not hoisted, only variables and functions. Now let’s take this one step further to see the other ways you can get an undefined output through improper code practices with variables inside the function. Take the following code as an example for when you may run into an undefined output.
// Undefined
var outputValue = 'first string';
(function() {
console.log(outputValue);
var outputValue = 'local string';
})();
Applying what we already know about hoisting, you can gather one major takeaway from the previous code example. The local variable inside the function is going to be hoisted to the top, thus clobbering the first variable. Since initializations are not hoisted, the output of this function would come out to be undefined.
Overall, this behavior needs to be kept in mind while writing functions in JavaScript. A good way to avoid the previous problem is to simply place the variables at the top of the local area in the function (hoist them yourself). It is always good to be conscious where you place your code, when dealing with hoisting of functions.