hoisting is the processing of declarations before any code is executed.
What's a declaration though?
const
, let
, and var
)function f(x) {}
)
Hoisting basically brings declarations to the top of the current scope. What does that mean for us? →
(btw, this article explained a lot, as well as Chapter 4 in Speaking JavaScript)
So… we basically know what happens here. What's the output of the following code examples? →
f();
function f() {
console.log("TO THE TOP, PLZ!")
}
output: TO THE TOP, PLZ!
f();
var f = function() {
console.log("TO THE TOP, PLZ!")
}
output: TypeError: undefined is not a function
f();
output: ReferenceError: f is not defined
What's the output of this code? →
function outer() {
inner();
function inner() {
console.log('hello');
}
}
outer();
hello
is printed out. What happens if we add in a call to inner at the end, outside of the function
?
// same as above (function outer() ... )
// but add the line below at the very end
inner();
ReferenceError
- function declarations are hoisted to the top of their current scope (not to the top of the global scope)
var
Declarations?var f = function ...
behaves the we way it does)var
ExamplesTreating each code example as a completely separate program, what is the output of the following lines of code? →
console.log(x);
// variable not yet declared (easy)
ReferenceError: x is not defined
var x;
console.log(x);
// x is declared before ... works obvs!
undefined
// so... what do we get here?
console.log(x);
var x;
undefined
Note that the last example would be an error if using let
(or const
)
var
Declarations are Hoisted
console.log(x);
console.log(y);
var x;
var y;
In the above example:
undefined
twice rather than ReferenceError
var
?Let's start simple. What's the output of this code?
var x = 5;
console.log(x);
// no surprise here!
5
But how about this? →
console.log(x);
var x = 5;
// oof. what!?
undefined
var
and Initializationvar
declarations are hoisted
console.log(x);
var x = 5;
var x;
console.log(x);
x = 5;
var
and HoistingThis probably doesn't matter since, we all know that you should never declare a variable without var, but:
ReferenceError
// (all we did here was take out var!)
console.log(x); // oops ... ReferenceError
x = 5;
let
and const
?As we saw previously, let
and const
have a Temporal Dead Zone →
let
and const
cannot be accessed…
let
or var
declaration
console.log(x);
let x = 5;
This is all you need to know about hoisting:
let
and const
declared variables cannot be accessed until their declaration (this is actually sane)var
declarations and function declarations are brought to the beginning of their enclosing scope
var
declarations are hoisted, but the assignment part occurs where the original statement was locatedvar
declarations that haven't been assigned a value yet are initialized with undefined
(just like let
)const
, let
, or var
) are not hoisted (but you always use let
, const
or var
, so not relevant, right?)What's the output of the following code? →
var num = 1000;
f();
function f(){
console.log(num)
var num = 5;
};
undefined
num
is not usednum
within the function is hoisted to the top of its enclosing scope, the function, f
undefined
What's the output of the following code? →
console.log(f);
var f = function(x) {
console.log("hello " + x);
}
undefined
- the declaration is hoisted
// it's executed as if it were
var f;
console.log(f);
f = function(x) {
console.log("hello " + x);
}
What's the output of this code? →
var inner = 1000;
function outer () {
inner = 5;
function inner() {}
}
outer();
console.log(inner);
1000
inner
is hoisted to the top of the enclosing scopeinner = 5
, a reassignment of the local inner
, not the globalWhat's the output of this code? →
console.log(f);
const f = function() {
console.log('I am function!');
}
ReferenceError
(temporal dead zone for const and let; used before declared)
And that's why the following gives us undefined is not a function
→
f();
var f = function(x) {
console.log("hello " + x);
}
f
is hoistedundefined
)undefined
as a functionHoisting. Why? →
var
, I don't know if I can excuse that!Like the one we saw before:
var num = 1000;
f();
function f(){
console.log(num)
var num = 5;
};
How can we get around this ambiguity? →
Always declare your variables at the beginning of your function!
Aaaaand… possibly, avoid using var
; use let
and const
instead!