Normally you know that you can only reference a variable or call a function after it’s been defined.
It’s normal to think like that, too. First you define something, then you use it.
But JavaScript before executing your code might reorder it according to some rules, and if you’re not careful you might be surprised.
Let’s see.
We have 2 special cases:
- variables defined with
var
- functions declared with the traditional function syntax
For variables, we can initialize a variable before declaring it:
test = 'hello'
var test
console.log(test) //'hello'
And for functions, we can call the function before declaring it:
bark() //'woof!'
function bark() {
console.log('woof!')
}
Sounds like crazy, right? We can call the function before declaring it? And also set the variable value!
This happens because JavaScript before executing the code actually moves all var
variable declarations, and traditional function declarations, on top.
This is called hoisting.
To avoid confusion, I always recommend to declare var
variables at the beginning of a function.
Or to not use var
at all, because let
and const
declarations do not suffer from this.
If you try changing var test
to let test
, you’ll get an error
ReferenceError: Cannot access 'test' before initialization
The same goes if you use an arrow function or also a function expression:
bark()
var bark = function() {
console.log('woof!')
}
In this case you’ll see an error
TypeError: bark is not a function
Lessons in this unit:
0: | Introduction |
1: | Global scope |
2: | Function scope |
3: | Block scope |
4: | Shadowing |
5: | ▶︎ Hoisting |
6: | Closures |
7: | An issue with `var` variables and loops |
8: | The event loop |