1
+ /********************************************************************************************
2
+ * Execution Context in Detail - Hoisting
3
+ * --------------------------------------
4
+ *
5
+ * We can associate an execution context with an object, i.e., an execution context can be
6
+ * thought of as an object. This object (i.e., the execution context) has 3 properties,
7
+ * namely:
8
+ * 1. Variable Object (VO): contains function arguments, function's inner variable
9
+ * declarations, as well as function declarations.
10
+ * 2. Scope Chain: contains current variable's objects as well as variable objects of all its
11
+ * parents.
12
+ * 3. "this" variable: which is an object that refers to the current execution context's
13
+ * object.
14
+ *
15
+ * How's this execution context actually created?
16
+ * -> By what we already know, we can say that when a function is called, a new execution
17
+ * context is created on top of the stack.
18
+ * This happens in two phases:
19
+ *
20
+ * 1. Creation Phase: In this phase, again there are 3 phases:
21
+ * 1. Creation of the Variable Object (VO).
22
+ * 2. Creation of the Scope Chain. [Huge topic, we'll know about
23
+ * this topic later]
24
+ * 3. Determine the value of the "this" variable.
25
+ *
26
+ * 2. Execution Phase: The code of the function that generated the current execution
27
+ * context is run line by line & all the variables are defined.
28
+ * If it is a global execution context, then the global context's
29
+ * code is executed line by line.
30
+ *
31
+ * 1.2. Creation of the Scope Chain:
32
+ * Q. What does scoping mean?
33
+ * A. Scoping answers the question of "where can we access a certain variable?"
34
+ *
35
+ * Scope in JS:
36
+ * -----------
37
+ * In JS, each new function creates a new scope. Scope is the space/environment,
38
+ * in which the variables it defines are accessible. In many other programming
39
+ * languages like C/C++/Java/Python/etc, a scope is simply created by the control
40
+ * structures like if, while(), for(), etc. But in JS, only a function can create
41
+ * a new scope.
42
+ *
43
+ * Lexical Scoping:
44
+ * ---------------
45
+ * In JS, we have Lexical Scoping, it means that, when "a function that is
46
+ * defined (lexically) within another function, gets access to the scope of the
47
+ * outer function".
48
+ *
49
+ * We'll see lexical scoping, normal scoping & scope chain in action in the
50
+ * following examples below.
51
+ *
52
+ * For visual aid, follow this link:
53
+ * https://github.com/Ch-sriram/JavaScript/blob/master/JS-Behind-the-Scenes/assets/scope.pdf
54
+ */
55
+
56
+ /////////////////////////////////////////////////////////////////////////////////////////////
57
+ /* Lexical Scoping & Scope Chaining */
58
+ var a = "Hello!" ;
59
+ first ( ) ; // Possible due to Hoisting.
60
+
61
+ function first ( ) {
62
+ var b = "Hi!" ;
63
+ second ( ) ; // Possible due to Hoisting.
64
+
65
+ function second ( ) {
66
+ var c = "Hey!" ;
67
+ console . log ( a + b + c ) ;
68
+ // The statement above will execute without any errors because of scope chaining
69
+ // due to lexical scoping.
70
+
71
+ // finding variable - 'a': When the JS engine (V8 from Google, Spidermonkey from
72
+ // Mozilla, Chakra from Microsoft, etc) looks for variable - 'a', it will first look
73
+ // for 'a' in the second() function, if 'a' is unavailable in this current
74
+ // function's scope (which is second()), then the JS engine will look for 'a'
75
+ // in the function which is lexically scoped above the current function (which is
76
+ // first()). JS engine will do this until it finds the variable - 'a' going till
77
+ // the global scope. If the variable is not found anywhere, then there'll be a
78
+ // reference error by the JS engine.
79
+
80
+ // finding variable - 'b': When the JS engine looks for variable - 'b', it does not
81
+ // find it in the current scope which is second() function's execution scope.
82
+ // Therefore, due to lexical scoping, JS engine will find for variable - 'b' in the
83
+ // function that's directly scoped above this function, which is the first()
84
+ // function. We will find the variable - 'b' in the first() function itself.
85
+ // Therefore, variable - 'b''s value is taken from first() function's variable
86
+ // object.
87
+
88
+ // Scope is always chained lexically for every variable created in JS.
89
+ }
90
+ }
91
+
92
+ /////////////////////////////////////////////////////////////////////////////////////////////
93
+ /* Execution Stack vs Scope Chaining */
94
+ var w = "Hello!" ;
95
+ primary ( ) ; // Possible due to Hoisting.
96
+
97
+ function primary ( ) {
98
+ var x = "Hi!" ;
99
+ secondary ( ) ; // Possible due to Hoisting.
100
+
101
+ function secondary ( ) {
102
+ var y = "Hey!" ;
103
+ ternary ( ) ;
104
+ }
105
+ }
106
+
107
+ function ternary ( ) {
108
+ var z = "John" ;
109
+ console . log ( z ) ; // This will work fine because 'z' is found in this function's context.
110
+ console . log ( w + z ) ; // This will also work because 'w' is found in the global context.
111
+ console . log ( w + x + y + z ) ; // Reference Error. Why? (Reason given below)
112
+ // This function is lexically scoped with the global execution context.
113
+ // Therefore, the JS engine tries to look for variable - 'y' in the global execution
114
+ // scope & it doesn't find it there, because the global scope's variable object is
115
+ // scoped upwards of ternary() scope's variable object. Therefore, this will result in
116
+ // a reference error.
117
+ }
0 commit comments