Understanding JavaScript scope
May 18, 2020
Scope refers to which functions, variables and objects other functions, variables and objects are able to access when an application is run. It can seem confusing at first, but with a slightly strange example I will try and explain the basics unsing castles and emojis π€...
Global and local scope
Imagine a castle. There is the land outside the castle which is global
, and there is the land inside the castle which is local
. People in the castle can see out into the countryside and see what exists outside in global
, but people from global
can't see into the castle's local
environment.
1let barbarian = "π"; // Barbarians roam everywhere outside. Be careful! function castleWalls () { let guard = "π₯·"; // We have a few guards in the walls to protect us console.log([guard, barbarian]) // => ["π₯·", "π"] } castleWalls(); console.log(barbarian) // => "π" console.log(guard) // => `Uncaught ReferenceError: guard is not defined`
barbarian
is global, and guard
is local to the castleWalls
. What that means is that anything within the castleWalls
can "see" what is within itself, and what is on the outside.
- The
castleWalls
scope allows it to see the localguard
AND the globalbarbarian
. - The global scope cannot see the
guard
(because they hide behind thecastleWalls
!).
Multiple local scopes
Each function has it's own local scope but can't see into the local scope of others.
1let barbarian = "π"; function castleWalls () { let guard = "π₯·"; } function village () { let villager = "π©βπΎ"; console.log(villager); // => "π©βπΎ" console.log(barbarian); // => "π" console.log(guard); // => `Uncaught ReferenceError: guard is not defined` }
Just as the barbarians cannot see into the castleWalls
, the same applies to the village
.
- The
village
can see the globalbarbarian
and it's own localvillager
. - The
village
cannot see into theguard
because it is local/inside thecastleWalls
. - The
castleWalls
is separate from thevillage
, it cannot see into thevillage
so it cannot seevillager
.
Essentially, everything can see out of it's own scope, but not into the scope of others, unless it is created inside of the other scope.
Nested local scope
A bit like in Inception, there are multiple levels of local scope. Each nested code block (for
loop, function
etc) has it's own scope. When these are nested within each other you end up with muliple levels of of local scope.
In the following example each "area" within the castle also has it's own local scope. A castle needs a inner wall, and a tower, so let's build them. They can see outwards, but not inwards.
1let barbarian = "π"; function castleWalls () { let guard = "π₯·"; function innerWalls () { let archer = "πΉοΈ"; function tower () { // The king is here! Long live the king! let king = "π€΄" console.log("Tower: ", [king, archer, guard, barbarian]) // => "Tower: " ["π€΄", "πΉοΈ", "π₯·", "π"] } console.log("innerWalls: ", [archer, guard, barbarian]) // => "innerWalls: " ["πΉοΈ", "π₯·", "π"] tower(); } console.log("outerWalls: ", [guard, barbarian]); // => "outerWalls: " ["π₯·", "π"] innerWalls() } console.log("global: ", [barbarian]) // => "global: " ["π"] castleWalls();
- In the
tower
, the king can see (has access to the scope of) the localtower
. - He also can see out from the tower and into the
innerWalls
(local), thecastleWalls
(local) and into the surrounding countryside (global
). - In the
innerWalls
, the archers cannot see the king, but they can see thecastleWalls
and their localguard
and can see out to the surrounding countryside (global
scope). - The
barbarians
can see nothing other than themselves or anything else in theglobal
scope.
Because everything within a scope gains that scope for itself it means that a nested block of code will gain the scope it has been created in. tower
gains the scope of innerWalls
because it has been created within inner walls. This continues up the chain until you reach the global
scope.
If you try to access king
, archer
, or guard
from outside the castle you will get Uncaught ReferenceError: king is not defined
because the global scope has no visibility inside the walls, or tower.
Note: Luckily in these example we have ninjas on guard, so the king is safe. Long live the king! π€΄