Skip to content

Commit 77b84fd

Browse files
committed
closure in details
1 parent a425fd6 commit 77b84fd

9 files changed

+168
-45
lines changed

Javascript/data-types.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ console.log("function type:", typeof
3232
```
3333

3434

35-
3635
In JavaScript, there are no true integers, all numbers are implemented in double-precision 64-bit binary format IEEE 754. When we use binary floating-point numbers, it will have some side effects. Here is an example of these side effects.
3736

3837
```js
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
3+
Closures
4+
The inner function can access the variables of the enclosing function due to closures in JavaScript. In other words, the inner function preserves the scope chain of the enclosing function at the time the enclosing function was executed, and thus can access the enclosing function’s variables.
5+
6+
The closure has three scope chains:
7+
8+
it has access to its own scope — variables defined between its curly brackets
9+
it has access to the outer function’s variables
10+
it has access to the global variables
11+
*/
12+
13+
var text = "outside";
14+
15+
function logText() {
16+
console.log(text); // ans: 'undefined'
17+
var text = "inside";
18+
console.log(text); // ans:'inside'
19+
}
20+
21+
logText();
22+
23+
/* When I run the above code, the first < console.log(text) > will print 'undefined' instead of 'outside' - Here's Why - when I have the variable 'text' declared and assigned both inside the function and outside the function -
24+
https://medium.com/backticks-tildes/understanding-hoisting-and-scoping-in-javascript-39ea7b41e31
25+
26+
In JavaScript, variables with the same name can be specified at multiple layers of nested scope. In such case local variables gain priority over global variables. If you declare a local variable and a global variable with the same name, the local variable will take precedence when you use it inside a function. This type of behavior is called shadowing. Simply put, the inner variable shadows the outer. This is how the Javascript interpreter finds a particular variable; it searches for the variable at the innermost scope being executed at the time, and continues until the first match is found, even if there are other variables with the same name in the outer scope.
27+
28+
So in above, it takes the 'text' declared inside the inside the function, but then only variable declaration is hoisted and NOT variable-assignment. So here, I am trying to print the 'outside' variable before assigning a value to it. So it prints undefined.
29+
30+
*/
31+
32+
var c = 15;
33+
34+
function outer() {
35+
console.log(c);
36+
// the above will print 'undefined' instead of '15'
37+
// because variable declaration is hoisted but not variable assignment,
38+
// And variable declared inside the function-scope will take precedence over the one declared outside
39+
40+
var b = 10;
41+
var c = 25;
42+
function inner() {
43+
var a = 20;
44+
console.log(a + b + c); // => but tis will will correctly print 55
45+
}
46+
return inner();
47+
}
48+
49+
outer();
50+
51+
/*
52+
53+
Final output from outer()
54+
55+
undefined
56+
55
57+
58+
59+
1 > https://medium.freecodecamp.org/javascript-closures-simplified-d0d23fa06ba4
60+
61+
Function outer() finishes execution, and all variables within the scope of outer() now no longer exist.
62+
This last part is important to understand. Once a function completes its execution, any variables that were defined inside the function scope cease to exist.
63+
64+
The lifespan of a variable defined inside of a function is the lifespan of the function execution.
65+
66+
What this means is that in console.log(a+b), the variable b exists only during the execution of the the outer() function. Once the outer function has finished execution, the variable b no longer exists.
67+
68+
*/
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
Lets look at this function
2+
3+
```js
4+
function outer() {
5+
var b = 10;
6+
function inner() {
7+
8+
var a = 20;
9+
console.log(a+b);
10+
}
11+
return inner;
12+
}
13+
14+
/*
15+
Here we have two functions:
16+
17+
an outer function outer which has a variable b, and returns the inner function
18+
an inner function inner which has its variable called a, and accesses an outer variable b, within its function body
19+
The scope of variable b is limited to the outer function, and the scope of variable a is limited to the inner function.
20+
21+
Let us now invoke the outer() function, and store the result of the outer() function in a variable X
22+
*/
23+
24+
var X = outer();
25+
```
26+
Since the variables X is functions, we can **execute** them. In JavaScript, a function can be executed by adding **()** after the function name, such as **X()**.
27+
28+
When we execute X(), we are essentially executing the `inner` function.
29+
30+
If I run < console.log(X()) > the output will be below
31+
32+
30
33+
undefined
34+
35+
So the closure function **inner**() is getting the value of **b = 10** from its enclosing **outer()** function ever after **outer()** function has returned.
36+
37+
#### Let’s see step-by-step what happens when the outer() function is first invoked:
38+
39+
- 1. Variable b is created, its scope is limited to the outer() function, and its value is set to 10.
40+
- 2. The next line is a function declaration, so nothing to execute.
41+
- 3. On the last line, return inner looks for a variable called inner, finds that this variable inner is actually a function, and so returns the entire body of the function inner.
42+
- 4. Note that the return statement does not execute the inner function — a function is executed only when followed by () — , but rather the return statement returns the entire body of the function.
43+
- 5. The contents returned by the return statement are stored in X.
44+
45+
Thus, X will store the following:
46+
47+
function inner() {
48+
var a=20;
49+
console.log(a+b);
50+
}
51+
52+
This can be easily verified by adding the following to the JavaScript code:
53+
54+
```js
55+
console.log(typeof(X)); //X is of type function
56+
```
57+
- 6. Function outer() finishes execution, and all variables within the scope of outer() now no longer exist.
58+
- 7. This last part is important to understand. Once a function completes its execution, any variables that were defined inside the function scope cease to exist.
59+
60+
The lifespan of a variable defined inside of a function is the lifespan of the function execution.
61+
62+
What this means is that in **console.log(a+b)**, the variable **b** exists only during the execution of the the **outer()** function. Once the outer function has finished execution, the variable b no longer exists.
63+
64+
This is the most important point to realize. The variables inside the functions only come into existence when the function is running, and cease to exist once the functions completes execution.
65+
66+
##### Now see the main point of this exercise - that how a closure function retains its enclosing function's variable values, even after the enclosing function has returned.
67+
68+
- A. When we execute X(), we are essentially executing the `inner` function.
69+
70+
- B. If I run < console.log(X()) > the output will be below
71+
72+
```
73+
30
74+
undefined
75+
```
76+
- C. So the closure function **inner**() is getting the value of **b = 10** from its enclosing **outer()** function ever after **outer()** function has returned.
77+
78+
#### Let us examine step-by-step what happens when X() is executed the first time:
79+
80+
- 1. Variable a is created, and its value is set to 20.
81+
- 2. JavaScript now tries to execute a + b. Here is where things get interesting. JavaScript knows that a exists since it just created it. However, variable b no longer exists. Since b is part of the outer function, b would only exist while the outer() function is in execution. Since the outer() function finished execution long before we invoked X(), any variables within the scope of the outer function cease to exist, and hence variable b no longer exists.
82+
83+
#### Closures
84+
85+
- A. The inner function can access the variables of the enclosing function due to closures in JavaScript. In other words, the inner function preserves the scope chain of the enclosing function at the time the enclosing function was executed, and thus can access the enclosing function’s variables.
86+
87+
- B. In our example, the inner function had preserved the value of b=10 when the outer() function was executed, and continued to preserve (closure) it.
88+
89+
- C. It now refers to its scope chain and notices that it does have the value of variable b within its scope chain, since it had enclosed the value of b within a closure at the point when the outer function had executed.
90+
91+
- D. Thus, JavaScript knows a=20 and b=10, and can calculate a+b.
92+
93+
So the inner function has three scope chains:
94+
95+
access to its own scope — variable a
96+
access to the outer function’s variables — variable b, which it enclosed
97+
access to any global variables that may be defined
98+
99+
##### Further Reading
100+
[https://medium.freecodecamp.org/javascript-closures-simplified-d0d23fa06ba4](https://medium.freecodecamp.org/javascript-closures-simplified-d0d23fa06ba4)

Javascript/js-basics/closure-tricky-GREAT-EXAMPLE.JS

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)