Skip to content

Commit be3677f

Browse files
Create Closures (#242)
1 parent f26ddef commit be3677f

File tree

1 file changed

+165
-0
lines changed

1 file changed

+165
-0
lines changed

Web Development/Frontend/Closures

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
Topic : Closures
2+
3+
1. LET KEYWORD
4+
5+
let allows you to declare variables that are limited in scope to the block, statement, or
6+
expression on which it is used. This is unlike the var keyword, which defines a variable
7+
globally, or locally to an entire function regardless of block scope.
8+
9+
1.1. Scoping Rules
10+
11+
Variables declared by let have their scope in the block for which they are defined, as
12+
well as in any contained sub-blocks. In this way, let works very much like var. The
13+
main difference is that the scope of a var variable is the entire enclosing function:
14+
function varTest() {
15+
var x = 1;
16+
if (true) {
17+
var x = 2; // same variable!
18+
console.log(x); // 2
19+
}
20+
console.log(x); // 2
21+
}
22+
function letTest() {
23+
let x = 1;
24+
if (true) {
25+
let x = 2; // different variable
26+
console.log(x); // 2
27+
}
28+
console.log(x); // 1
29+
}
30+
31+
Let in for loop – Consider the following for loop.
32+
for(var a = 1; a < 5; a++){
33+
setTimeout(function(){
34+
console.log(a)}, 1000);
35+
}
36+
The loop will print 5 5 5 5 instead of 1 2 3 4. The short answer for this phenomena
37+
is, that the for loop executes first, then it looks for the a value, which is 5, and then
38+
outputs four times, one for each loop iteration.
39+
for (let a = 1; a < 5; a++) {
40+
setTimeout(function () {
41+
console.log(a)
42+
}, 1000);
43+
}
44+
This loop will print 1 2 3 4. Every round of let creates a new variable and bounds it
45+
with the closure.Let a gets a new binding for every iteration of the loop. This means
46+
that every closure, if function is created in loop captures a different a instance.
47+
EXTRA:
48+
You can read about let from the links below -
49+
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
50+
https://www.geeksforgeeks.org/difference-between-var-and-let-in-javascript/
51+
52+
53+
2. EXECUTION CONTEXT AND LEXICAL ENVIRONMENT
54+
55+
56+
2.1. Execution Context
57+
58+
When your code runs in the JavaScript Engine. Each statement of your code is
59+
executed in a certain Execution Context.In JavaScript environment there are 2 main
60+
types of Execution Context. First is Global Execution Context,when your code is
61+
initially run even if it’s spread across to a page using a <script /> tag, JavaScript
62+
creates one Global Execution Context in which your code was placed in when they
63+
execute and runs inside the browser. Second is the Function Execution Context
64+
from the word itself it was created when you invoked the function that you define.
65+
Each time you invoked a function it will create a new Function Execution Context.
66+
var message = ‘Hello there’;
67+
function foo(message) {
68+
bar(message);
69+
}
70+
function bar(message) {
71+
console.log(message);
72+
}
73+
foo(message);
74+
Initially Execution Context Stack is empty.
75+
When this code runs, JavaScript engine create one Global Execution Context and
76+
push it to Execution Context Stack.
77+
When we call the function foo, Global Execution Context was paused because
78+
JavaScript is a single threaded environment they can only execute one code at a
79+
time. After that JavaScript engine will create a new Function Execution Context for
80+
foo and push it into Execution Context Stack.
81+
When foo function is executed we invoked the bar inside foo definition. JavaScript
82+
engine paused the execution context in foo function and creates a new Function
83+
Execution Context for bar and pushed it into stack.
84+
After the bar was finished executing it will popped out in the Execution Context
85+
Stack and go back to foo and resume its execution. Same process will applied to the
86+
foo until we finished and go back to the Global Execution Context and resume the
87+
execution.
88+
89+
2.2. Lexical Environment
90+
91+
Consider the following code
92+
var a = ‘a’;
93+
function foo() {
94+
var b = ‘b’;
95+
function bar() {
96+
var c = ‘c’;
97+
console.log(c); // You can access me here.
98+
console.log(b); // You can access me too..
99+
console.log(a); // You can also access me..
100+
}
101+
bar();
102+
}
103+
foo();
104+
When this code runs initially a Global Environment was created and a and foo was
105+
stored in that. When we invoked the function foo below a new environment was
106+
created and stored the variable b in foo environment which is only visible to bar
107+
function because bar is an inner function in foo environment. When invoking the
108+
foo() we also called the bar() function which is also creates a new environment for
109+
their definition.
110+
Whenever we call a function, a new function execution context is created and
111+
pushed into execution context stack with a new associated lexical environment.
112+
113+
Inside the bar function we do logging to checks if the variables that we create is
114+
visible and if we can access it in their environment.
115+
When variable c was logged in the bar environment, it was displayed successfully
116+
obviously because it was inside his environment.
117+
However when when we do logging the variable b and variable a it was also
118+
successfully displayed.How did this happened?
119+
This is because, In the second logging we call the variable b which is not in bar
120+
function scope. So javascript does this internally to search it in other Outer
121+
Environment until they found that variable. In our case, they found the variable b at
122+
foo function since the bar function has reference to foo function the foo function
123+
environment is not pop out in the Execution Context! When variable a was logged it
124+
was also successfully displayed because variable a is stored in the Global Execution
125+
Context. Everyone can access the Scope in the Global Execution Context.
126+
127+
EXTRA:
128+
You can read about them from the links below -
129+
https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript1c9ea8642dd0
130+
131+
132+
3. CLOSURES
133+
134+
135+
A closure is a feature in JavaScript where an inner function has access to the outer
136+
(enclosing) function’s variables—a scope chain.
137+
The closure has three scope chains:
138+
● it has access to its own scope—variables defined between its curly brackets
139+
● it has access to the outer function’s variables
140+
● it has access to the global variables
141+
A closure is created when an inner function is made accessible from outside of the function
142+
that created it. This typically occurs when an outer function returns an inner
143+
function. When this happens, the inner function maintains a reference to the environment
144+
in which it was created. This means that it remembers all of the variables (and their values)
145+
that were in scope at the time. The following example shows how a closure is created and
146+
used.
147+
function add(value1) {
148+
return function doAdd(value2) {
149+
return value1 + value2;
150+
};
151+
}
152+
var increment = add(1);
153+
var foo = increment(2);
154+
// foo equals 3
155+
From the above example, we can make following observations -
156+
Thee add() function returns its inner function doAdd(). By returning a reference to an inner
157+
function, a closure is created.
158+
“value1” is a local variable of add(), and a non-local variable of doAdd(). Non-local variables
159+
refer to variables that are neither in the local nor the global scope. “value2” is a local
160+
variable of doAdd().
161+
When add(1) is called, a closure is created and stored in “increment”. In the closure’s
162+
referencing environment, “value1” is bound to the value one. Variables that are bound are
163+
also said to be closed over. This is where the name closure comes from.
164+
When increment(2) is called, the closure is entered. This means that doAdd() is called, with
165+
the “value1” variable holding the value one

0 commit comments

Comments
 (0)