Unlike languages like C, variables and functions in JavaScript are not declared at the point of use. Instead, no matter where functions and variables are declared, they are moved to the top of their scope hoisted
and assigned a default value of undefined until they're reached in code, while assignments are left in place.
What really happens, is that during compile time, the declarations are put into memory first, but physically remain in place in code. What this means is that you get access to functions and variables before they’re declared in code.
This only applies to declarations, not to expressions, and not to initializing an undeclared variable.
Example:
will produce the same output as declairing it before.
Variable Hoisting
When a variable declaration is encountered by the interpreter, it creates storage for that variable. This storage contains the value undefined until it is assigned in the code.
For example, the following code defines the variable after the value has already been set and accessed. However it will still function corectaly and output: Set the value
The keyword used when defining a variable will determine whether or not the variable is hoisted.
Variables defined with the keyword var
are hoisted, and variables defined with the keyword let
and const
are not.
Hoisted variables
Not Hoisted variables
ReferenceError: Cannot access 'a' before initialization
Variable Hoisting Scope
When the variable is used inside a scope, the variable is hoisted only to the top of the scope. For example, the variable a
defined inside this function will only be hoisted to the top of the function, resulting in a ReferenceError: a is not defined
when accessed at the bottom of this script.
In the above example, variable a
is hoisted to the top of its scope and is only accessible inside the functionScope
function.
Function Hoisting
Function hoisting works similarly to variable hoisting; this is why you can call a function in code before you declare it.
An error occurs if a function is used as an expression as only declarations are hoisted.
Best Practices
Hoisting can cause undesirable and difficult-to-debug outcomes.
It is best to avoid hoisting issues and declare variables and functions first before using them. When defining variables, unless you have a specific need, it's generally better to use let than var.