Hoisting in JavaScript
Hoisting is the process of lifting and declaring a variable defined with
var
to the top of its scope, be it functional scope (if defined in function) or global scope (if declared outside of a function). Additionally, function declarations are hoisted to the top of the current scope as well.
Let’s dive into some code.
Hoisting Variables
So now that we have our definition, what do we mean by “lifted and declared”?
The above is actually executed as the following:
We can see the difference between declaring a variable (that is hoisted) and not declaring a variable at all.
Let’s go a bit further, what about variable hoisting within a function?
Given that there is no block scope when using var
, the variable x
is hoisted to the top of the function.
As variables as hoisted, so are function declarations.
Hoisting Functions
Function declarations are hoisted to the top of the scope chain.
Function expressions are not hoisted.
Function hoisting overrides variable hoisting.
For reference, if we did not have the function declaration, our log statement would print undefined
Initializing our variable will override the function declaration.
This is because during execution, the above example is actually changed to the following:
Confusing, no? Shouldn’t what we write at author time (i.e. the lexical scope) be the same as what is happening during execution? Why yes, yes it should be. Enter ES6!
ES6 Block Scope and Hoisting
The good news is that block scope helps us avoid pitfalls introduced with hoisting. Let’s bring back our previous example using let
and const
instead of var
.
Using let
in this manner will trigger a ReferenceError
.
And we will get the same error with const
.
In this case, the errors are a good thing! We do not want to inadvertently access a variable before we have declared and initialized it. This will help us create cleaner and more maintainable programs as the JavaScript engine will execute the code in the order that we write it (i.e. author time).
Conclusion
Identifiers (i.e. variables) declared with the var
keyword are created as if they are defined at the top of the scope (be it function or global). This process is called “hoisting” and applies to variables defined with var
and function declarations.
While block scope with const
and let
allows us to avoid the pitfalls of hoisting when writing modern JavaScript, it is still important to understand this concept as you may work in a mixed code base (e.g. ES5 and ES6), are writing ES5 and below based on your requirements, or are simply curious of the many JavaScript quirks and are targeting a 100% completion rate.
Check out the further reading below and happy coding!
Additional Resources
- Hoisting definition by Mozilla
var
definition from Mozilla- JavaScriptIsSexy on variable hoisting
- Getting back to basics on JavaScript Hoisting with Sitepoint