Understanding Lexical Scope In JavaScript
Lexical Scope — The scope of a name binding — an association of a name to an entity, such as a variable — is the region of a computer program where the binding is valid
Scope
Scope Simply determines the visibility of variables through a certain set of rules which are set in place and change depending on the Language you are programming in — Thats it, not too complicated!
Lexical Scope
Lexical Scope, is a type of scope — Sometimes also referred to as Static Scope
. Lexical Scoping simply defines how variable names are resolved in nested functions e.g nested functions contain the scope of parent functions.
It’s important to remember that in a Lexically Scoped language, scope is based on compile time for the remainder of that scope no matter what shape or form it may take in the future.
Digging Deeper
Disclaimer: I am no compile theory expert, this is just my observations through my own findings with javascript.
JavaScript is a Compiled Language
Yes, you heard that correctly. JavaScript is not an interpreted language like you may think, even though it may seem like it if you have ever programming in languages like C++.
For simplicity sake (and because I am no compile theory expert) I like to think of JavaScript as a two pass language that first parses the code and sets up a mental model of the different scopes available and then again goes through and actually executes the map.
The parsing stage is done by the compiler
through something called lexing
it is in this phase that scopes get defined. Later on, the engine
comes through and executes the code and already knows exactly what is available to each variable because the compiler already did the work for the engine. Cool right?
Lets Learn through a practical example:
Taking it step by step:
Line 8
: We declare a variable in theGlobal
ScopeLine 10
: This is a new function and thus generates a newexecution context.
We give it the name[F]
to represent the foo scope. 🚨 It’s important to remember that the argument passed intofoo()
is actually apart of thefoo()
scope since this variable is ONLY used and available in that scope.Line 11
: We create a variable named b and assign it the valuea * 2
which will also belong to thefoo()
scope.Line 13:
This is a new function and thus generates a newexecution context
. We give it the name[B]
to represent the bar scope. 🚨 It’s important to remember that the argument passed intofoo()
is actually apart of thebar()
scope since this variable is ONLY used and available in that scope.Line 14:
Weconsole.log
our variablesa, b, c
. Remember, we have access to these because of Lexical Scope e.g (we are in a nested function and have access to those variable in the surrounding scopes).Line 14:
Don’t clarify this in the example, butconsole.log
is apart of theGlobal
scope since that is not a function we define but a function JavaScript gives to us by default in all programs.Line 17:
We execute the functionbar(b * 2)
which lives inbar()'s
scope.Line 18:
We execute the functionfoo(3)
which lives in theGlobal
scope.
Here are some alternative explanations that may be easier to understand:
- Lexical Scope — Simply a rule for where to look for things.
- Lexical Scope — Where I save my function determines what data it will have access to for the remainder of the lifetime of that function no matter what label I give to it in the future.
- Lexical Scope — Can alternatively be thought of as compile time scope e.g At the time of writing code, the decisions for how scoping is to be made.
Conclusion
We have gone over how JavaScript heavily depends on its own scoping rules. JavaScript uses a scoping rule which is known as lexical scope
a scoping rule which states any inner function has access to surrounding scopes if it needs to, and will continue to search in a bubble up fashion until it has found it or hit the global scope in which case will throw an error.
I hope this has been helpful in understanding how lexical scoping works for you and as always if you have any questions I will be happy to answer in the comments section. 😃