Hoisting
Hoisting describes when memory is set aside for variables within a given scope.
The basic concept of hoisting is that any variable that is declared is available at all times within it's given scope. This means that even though a variable does not have a set value, it can be referenced and even used as log as there is a variable declared in the current scope.
See the difference between the two uses of newVar
in the following functions:
var noHoisting = function() {
console.log(newVar); // Reference Error: newVar is not defined
}
var hoisting = function() {
console.log(newVar); // undefined
var newVar = `Make a new var`;
}
Variable Declaration vs Assignment
Variables are declared by using the var
keyword.
This sets aside a piece of memory for storing the variable value.
All declarations are hoisted to the top of their scope and the variable will not make a reference error throughout that scope.
On the other hand, variables are assigned values by using the =
operator.
Until variables are given an initial value, they will be undefined
.
While variable declarations are hoisted, assignment is performed in order.
This means that a variable may unexpectedly be undefined
since it had not been assigned yet.
Function Declarations
Variable assignments are different than function declarations. Like variables, declared functions are hoisted to the top of their scope and can be used before they are declared.
Compare using function declarations compared to creating a variable and assigning it to a function expression:
iWorkUpHere();
iDontHoist();
function iWorkUpHere() {
console.log(`works everywhere`);
}
var iDontHoist = function() {
console.log(`doesn't work until later`);
};
iDontHoist(); // Would work here if no error from earlier
Avoiding Confusion and Code Quality
Since it can be confusing as to when a variable is set versus when hoisting occurs, it is a best practice to create the variable declaration at the top of your current scope. Even do this if it means separating declaration from initialization. See how this rewrite makes it cleaner to see when variables are available:
var confusing = function() {
console.log(newVar); // undefined
var newVar = `Make a new var`;
}
var clearer = function() {
var newVar;
console.log(newVar); // undefined
newVar = `Make a new var`;
}