What is Scope?
In simple terms, Scope can be defined as the space in which variables and statements are accessible.
or
Scope determines the accessibility of variables, objects, and functions from different parts of the code.
- Let's understand this definition with an example-
Example-
var x = 2
function myFunc(){
console.log(x)
}
myFunc function is able to access the variable x
thus we can say that x
is in scope of myFunc.
- Before ES6 (2015), there were only 2 types of scope (Global and Function) but in ES6, a new scope was introduced, namely the Block Scope.
3 types of Scopes:
Credits-Nemo
1. Global Scope-
- Variables declared globally/ in the global execution context have a global scope.
- They can be accessed from anywhere in the program.
- No matter whether they are declared using
var
,let
orconst
, variables declared in global scope behave similarly.
Example-
var x = 2
function myFunc(){
console.log(x)
}
Here the variable x
is declared in global scope thus it is available for use across the entire program.
- As explained in Part 3 of this Advanced JavaScript series, if a variable is declared without
var
,let
orconst
keyword, it always gets declared in the global scope.
Example-
function myFunc(){
x = 1
}
console.log(x)
Here the code gives output 1
since the variable x
gets declared in Global scope.
2. Function/Local Scope-
- Variables declared within a JavaScript function, become LOCAL to the function.
- These variables can only be accessible from within the function.
- These variables are removed from the memory when the execution of the function is completed thus the variable names can be reused in some other functions.
- All
var
,let
andconst
work similarly in Function scope.
Example-
function myFunc(){
let x = 1
console.log(x)
}
Here the variable x
is declared in the function/local scope thus accessible only from inside the function.
3. Block Scope-
- The two new keywords for variable declaration, that is
let
andconst
that were introduced in ES6 are Block Scoped. - Any variable that is declared within a pair of braces { } or a block and cannot be accessed from outside it are said to be Block Scoped.
Example-
var x = 1
if(x){
var y = 2
let z = 3
console.log("hello world")
}
console.log(y)
console.log(z)
Output-
2
Uncaught ReferenceError: z is not defined
Here, the variable y
cannot be accessed from outside the if block
because variables declared using let
are Block Scoped whereas variables declared using var
are not.
Lexical vs Dynamic Scoping-
- In Lexical(Static) Scoping, the structure of the program source code determines what variables you are referring to.
- In Dynamic Scoping, the runtime state of the program stack determines what variable you are referring to.
Lexical scoping refers to the variables in the location of a function's definition, whereas dynamic scoping refers to the variables in the location of a function's invocation.
- Let's understand with the help of an example.
Example-
Code-
function a() {
console.log(i);
}
function b() {
var i = 1;
a();
}
var i = 0;
b();
Explanation-
We have two function,
a
andb
.a
logs out the value ofi
which is set globally to0
.b
sets its value to1
, and callsa
. If we callb
, it will log out0
. This is because — whilea
doesn't have a variable calledi
—a
has access to the enclosing scope where the function is defined. And in the global scope, we have ani
which is set to0
. This is called lexical scoping.In dynamic scoping, the value of
i
will be1
. This is because instead of looking at where the function is defined, it looks at where it is called from. It sees from the call stack that it has been called fromb
, which sets the value ofi
to be1
.
- As you can see, lexical scope looks at where a function is declared, where dynamic scope refers to where a function is called from.
Credits-Thang Tran Duc
Connect with me-
Appendix-
- Advanced JavaScript Series - Part 1: Behind the scenes (JavaScript Engine, ATS, Hidden Classes, Garbage Collection)
- Advanced JavaScript Series - Part 2: Execution Context and Call Stack
- Advanced JavaScript Series - Part 3: Weird JS behavior, Strict Mode and Hoisting, Temporal Dead Zone
- Advanced JavaScript Series - Part 4.1: Global, Function and Block Scope, Lexical vs Dynamic Scoping
- Advanced JavaScript Series - Part 4.2: Scope Chains and their working, Lexical and Variable Environments
- Advanced JavaScript Series - Part 5: IIFE & 'this' keyword in JS(tricky Eg.), call(), apply(), bind(), Currying(Functional Prog)
- Advanced JavaScript Series - Part 6.1: Everything in JS is an Object? Weird JS behaviors revealed, Primitive Non-Primitive Types
- Advanced JavaScript Series - Part 6.2: Pass by Value & Pass by Reference, Shallow & Deep Copy, Type Coercion
- Advanced JavaScript Series - Part 7: First Class Citizens & Higher Order Functions
- Advanced JavaScript Series - Part 8: The 2 Pillars~ Closures & Prototypal Inheritance
- Advanced JavaScript Series - Part 9: Constructor Functions, Object Oriented,
new
keyword
Top comments (4)
Sorry but, scope in JS should be considered basic knowledge, not advanced.
Sorry, but I was reading an article the other day and it mentioned only two scopes, Global and Local but after ES6 there is Block scope as well so I thought I should add this topic as a part of the series as well. But there is more to this part, this is 4.1, more around this topic coming :)
Thanks for the arcticle man it was really helpful... get to know about lexical and dynamic scoping
Cool