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 scopeImagine 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.
castleWalls scope allows it to see the local guard AND the global barbarian.The global scope cannot see the guard (because they hide behind the castleWalls!).Multiple local scopesEach 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.
village can see the global barbarian and it's own local villager.The village cannot see into the guard because it is local/inside the castleWalls.The castleWalls is separate from the village, it cannot see into the village so it cannot see villager.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 scopeA 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 local tower.He also can see out from the tower and into the innerWalls (local), the castleWalls (local) and into the surrounding countryside (global).In the innerWalls, the archers cannot see the king, but they can see the castleWalls and their local guard and can see out to the surrounding countryside (global scope).The barbarians can see nothing other than themselves or anything else in the global 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.