# Scope and Hoisting
# Scope
Scope is a term that describes where a variable can be accessed. When declared with the keyword var
a variable has two possible scopes - global or function.
If a variable is declared outside of any function then it has global scope and can be accessed from anywhere.
If a webpage loads multiple script files, global variables from either file can be seen anywhere inside either file.
If the variable is declared inside a function then that function was the limit of its scope. It gets created when the function runs and is discarded when the function finishes running. (Unless there is a closure...but that is a story for another day)
Variables declared with either let
or const
are block scoped. This means that they can be global variables OR they are scoped inside the closest pair of curly braces.
let g = "global";
function f(a) {
let b = 2;
console.log(a, b, g); //all these work here
if (b < 5) {
let c = 3;
console.log(g, a, b, c); //all these work here
console.log(d); //FAIL
} else {
let d = 4;
console.log(g, a, b, d); //all these work here
console.log(c); //FAIL
}
}
f(1);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
In this example, g
is a global variable that can be accessed and used anywhere in the code.
The variables a
and b
are scoped to the function. They can be used anywhere inside the function.
The variables c
and d
can only be used or accessed inside the first or second part of the if else
where they were declared.
# Hoisting
When a script is run, function declarations and variable declarations using var
are hoisted to the top of their scope. This way all the code inside their scope is aware of their existence before the code runs.
However, variables declared with var
will be given the automatic value of undefined
until the original line where they are assigned the value is reached.
Function declarations are hoisted to the top of their scope so that the function can be run from anywhere in the code.
Variables declared with let
or const
will be hoisted to the top of their scope but they are not given the value undefined
until the line of code where they were actually declared is reached.
The automatic assignment of undefined
to variables declared with var
was seen as encouraging bad habits that lead to too many errors. That is why this practice was not continued with let
and const
.
let a; //at the start of running the code a has the value undefined.
console.log(a); //undefined
console.log(b); // ReferenceError - script will stop running
console.log(c); //undefined
a = 3;
let b = 4;
var c = 5;
console.log(a); // 3
console.log(b); // 4
console.log(c); // 5
2
3
4
5
6
7
8
9
10