# JavaScript 運作原理(2) - Execution Stack, Scope Chain ### Conceptual Aside: *Single Threaded,* *Synchronous Execution* #### Single Threaded > **One Command Is Executed At a Time** - Single threaded execution means you're **only doing one at a time**. - When we're dealing with browsers, understand that JavaScript isn't the only thing happening in the browser. So, when we say JavaScript is single threaded, It may not be under the hood of the browser, but from our perspective as programmers, JavaScript behaves in a single threaded manner. #### Synchrous: > **One At a Time** (and In Order...) - One line of code being executed for synchronous execution at a time. And for our purposes, in order. So the code is executed one line at a time in the order that it appears. **Single threaded synchronous execution, meaning that in JavaScript, only one thing is happening at a time.** --- ### Function Invocation > **Running (calling) a Function** - In JS, by using `()` - When we say we invoke the function or function invocation, it means: run the function. <br> --- ## Execution Stack - Anytime you execute or invoke a function in JavaScript: - **A new execution context is created for that function put on the execution stack** - **'this'** variable is also created for that function - The variables and functions within it are set up during the creation phase. - And the code is executed line by line during execution phase. - Execution stacks : one on top of the other on top of the other. - **Which ever one is on top is the one that's currently running** - When the function finishes, it's popped off the execution stack. ( Every time a function is invoked, even if it's invoking itself, a new execution context is created, put on top of the stack ) #### Example ```+ function a(){ b(); var c; } function b(){ var d; } a(); var d; ``` ![](https://s3.us-west-2.amazonaws.com/secure.notion-static.com/03965ee1-c09c-49fe-a147-54c8fbb5bfe1/Screen_Shot_2021-05-11_at_2.55.15_PM.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20210713%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210713T094951Z&X-Amz-Expires=86400&X-Amz-Signature=3d4ffcfd3f67fca4b497d47d117587e88a07b5a6ca9010780cbc44965936edfc&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22Screen_Shot_2021-05-11_at_2.55.15_PM.png%22 =300x) ***What's going to happens (in details)?*** 1. **Create** Global Execution Context 2. Global Execution Context **Creation Phase**: - Create global object and variable 'this', - Attached funciton a, function b, var d to the global object, set up a, b, d memory space 3. Global Execution Context **Excution Phase**: - The code will be executed line by line, one after another. (It won't execute anything code in function a and function b because they haven't been invoked.) - When it hit `a();` , it invoke/call/run function a 4. A new execution context `a()` is created and placed on **execution stack**. Code inside function a become the currently running code ( The very last line `var d;` is not going to be run yet since JS is synchronous ) What's running is the current code within the current execution context (Which is the one at the top of the stack) - **Creation phase** It will have it's own space for variables and functions. - **Execution phase** Execute line by line the code within the function It hit the line that invoke `b();`, it's going to **stop at that line of code and create another execution context** and run that code. 5. Anothe new execution context `b()` is created, which **becomes the top of the stack** - Creation phase (variable var d in memory) - Execution phase ( the code inside function b is running line by line) 6. Only when execution of `b()` finishes will we go back to finishing `a()`. ( Because when the function finishes, the execution context is **popped off of the stack**.) 7. Now, current execution context become `a()` So it runs the next line of code that hadn't yet been run inside that execution context (Meaning that `var c;` line) 8. When `a()` is finished, it get popped off the stack 9. Back to Global execution context The next line of code that hasn't yet been run in the global execution context is run, which is that very last `var d;` --- ### Variable Environment > **Where the variables live** - And how they relate to each other in memory (Think about: "where is the variable") - Every execution context has its own variable environment - The variable are attached to the variable environment of its own execution context. ```javascript function b(){ var myVar; console.log(myVar); } function a(){ var myVar = 2; b(); console.log(myVar); } var myVar = 1; a(); console.log(myVar); // undefined // 2 // 1 ``` ![](https://s3.us-west-2.amazonaws.com/secure.notion-static.com/6b597bdb-f8b1-4adb-9e7b-a6fe3318e577/Screen_Shot_2021-05-12_at_3.50.42_PM.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20210713%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210713T095126Z&X-Amz-Expires=86400&X-Amz-Signature=1b75bc344ec35a8847cb52eb50eac67d875febfccef480aeaa3ed82216cf471c&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22Screen_Shot_2021-05-12_at_3.50.42_PM.png%22 =300x) ### Scope > **Where the variable is available in your code** - Where are we able to see the variable? **⭐ Each variable is defined within its own execution context.** If a variable is defined inside a function, every time you call a function you get your own execution context. **What happened (in detail)?** 1. The **global** execution context is created : - Bottom `myVar` is put into memory space ⭐ In the case of the global execution context, it's variable environment is the global object. 2. The code in **global** execution context is executed : - memory space of `myVar` will get a value of 1 when it hits that `myVar = 1` line. - hit invocation of function `a` 3. A new execution context is created for `a()` ⭐ **`myVar` here will be put into its own variable environment of `a()` execution context .** - Its value will then be 2 during the execution phase when that line `myVar = 2` is run - Then it hit invocation of function `b` 4. A new execution context is created for `**b()`** , with its own variable environment. - Its own memory space for its variables `MyVar` is created, with a value of `undefined` when we log it 5. When `b()` finishes, it's back to the a() execution context, because the `b()` execution contexts have been popped off the stack. - The currently running context is the a() execution context - `myVar` in a() execution context with its own variable content is set to `2`. 6. When `a()` finishes, it's back to the global execution context. - The currently running context is the global execution context - `myVar` in global execution context with its own variable content is set to `1`. **So even though the `myVar` Is declared three times. They're distinct, and they don't touch each other.** --- ## Scope Chain ##### Example ```javascript= function b(){ console.log(myVar); } function a(){ var myVar = 2; b(); } var myVar = 1; a(); //1 ``` - Each execution context has some special things that get created for you like the variable `this`, and also, a reference to its **outer environment**. - There is no `myVar` in `b()` execution context variable environment. - But when we request a variable, JavaScript does more then just look in the variable environment of the currently executing context, but also its reference to outer environment. - In the case of function b, it's outer environment is the Global Execution Context, since function b **lexically sits on top of the global environment** ![](https://s3.us-west-2.amazonaws.com/secure.notion-static.com/9991e9cd-8114-4a94-a834-748cba6a879d/Screen_Shot_2021-05-12_at_7.15.20_PM.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20210713%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210713T095532Z&X-Amz-Expires=86400&X-Amz-Signature=c4917127060e4d935fc64bb4731bba7f5c4b0a6312f440179b12c400280692f4&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22Screen_Shot_2021-05-12_at_7.15.20_PM.png%22 =500x) ⭐ **The outer environment are we referring to is the lexical environment** JavaScript cares about the lexical environment when it comes to the outer reference that every execution context gets. (Where fuction b lexically sits ⇒ global environment , at which `myVar = 1` ) So, when we said inside function B console dot log MyVar it looked for MyVar, couldn't find it, and went down the scope chain. ### Concept - When you ask for a variable while running a line of code inside any particular execution context, if it can't find that variable it will look at the outer reference and go look for variables there, somewhere down below it in the execution stack. - And that outer reference where that points is going to depend on where the function sits lexically. (function a and function b both sits lexically in global environment, so outer environment of both a() execution context and b() execution context are global environment) ```javascript= function a(){ var myVar = 2; b(); function b(){ console.log(myVar); } } var myVar = 1; a(); console.log(myVar); // 2 // 1 ``` ```javascript= function b(){ console.log(myVar); } function a(){ var myVar = 2; b(); } a(); var myVar = 1; // undefined ```