|
| 1 | +# Episode 7 : Scope and Lexical Environment |
| 2 | + |
| 3 | +``` |
| 4 | +This is why JS is confusing (Case-1) |
| 5 | +
|
| 6 | +function a() { |
| 7 | + console.log(b); // surprisingly instead of printing undefined it prints 10. |
| 8 | + //So somehow this b could access the b outside the fun. |
| 9 | +} |
| 10 | +
|
| 11 | +var b = 10; |
| 12 | +a(); |
| 13 | +
|
| 14 | +--------------------- |
| 15 | +
|
| 16 | +Another case: (Case-2) |
| 17 | +
|
| 18 | +function a() { |
| 19 | + c(); |
| 20 | + function c() { |
| 21 | + console.log(b); // when cursor comes here, it still prints out 10 somehow!! |
| 22 | + } |
| 23 | + } |
| 24 | + var b = 10; |
| 25 | + a(); |
| 26 | + |
| 27 | + -------------------- |
| 28 | + |
| 29 | + Another one (DJ KHALED!) (Case-3) |
| 30 | + |
| 31 | + function a() { |
| 32 | + var b = 10; |
| 33 | + c(); |
| 34 | + function c() { |
| 35 | + console.log(b); //it prints the right value. How? See ans below Summary part |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + a(); |
| 40 | + console.log(b); // now when cursor comes here, it prints NOT DEFINED! |
| 41 | +
|
| 42 | +``` |
| 43 | + |
| 44 | +- This is the intuition behind **scope** |
| 45 | +- Scope is directly dependent on the lexical environment |
| 46 | +- **Lexical Environment** : local memory + lexical env of its parent |
| 47 | +- Whenever an EC is created, a Lexical environment(LE) is also created and is referenced in the local EC(in memory space) |
| 48 | +- Lexical means hierarchy. In the DJ KHALED (xD) code, function c is lexically inside function a. |
| 49 | +- So in EC of c(), variables and fun in c (none) + reference of lexical env of parent a() is there |
| 50 | +- LE of a() in turn is its memory space + reference to LE of parent (Global EC) |
| 51 | +- LE of Global EC points to *null* |
| 52 | + |
| 53 | + ``` |
| 54 | + To summarize the above points: |
| 55 | + |
| 56 | + call_stack = [GEC, a(), c()] |
| 57 | +
|
| 58 | + Now lets also assign the memory sections of each execution context in call_stack. |
| 59 | +
|
| 60 | + c() = [[lexical environment pointer pointing to a()]] |
| 61 | +
|
| 62 | + a() = [b:10, c:{}, [lexical environment pointer pointing to GEC]] |
| 63 | +
|
| 64 | + GEC = [a:{},[lexical_environment pointer pointing to null]] |
| 65 | +
|
| 66 | + ``` |
| 67 | + ### For case -3 |
| 68 | + - First JS engine searches for b in local mem of c(). Nothing is there. |
| 69 | + - So it goes to the reference of Lexical env of parent a(). Here b = 10 is here. So it takes this value, goes back to c() and console prints it. |
| 70 | + - Had b not been in a(), then pointer would have gone to a()'s parent (Global EC and searched there). Had b not been there too, then it goes to LE of global's parent |
| 71 | + which is null. Now JS engine stops and says b is NOT DEFINED. |
| 72 | + - **Lexical env of c = Local memory of c + LE of A + LE of Global** |
| 73 | + - This process of going one by one to parent and checking is called **scope chain** |
| 74 | + |
| 75 | + |
| 76 | + |
| 77 | + |
| 78 | + |
| 79 | + |
| 80 | + |
| 81 | + |
| 82 | + |
| 83 | + |
0 commit comments