Update: Thank you for your support, recently toss a summary of information, convenient for you to read the system, there will be more content and more optimization, click here to view
—— The following is the text ——
The topic of this installment is the call stack. There are 28 installments in this installment, each of which focuses on an interview challenge. If you’re not familiar with this advanced installment, click on the end of this installment to see the full article.
If you think this series is good, welcome to like, comment, forward, your support is the biggest power OF my persistence.
An execution context is an abstraction of the context in which the current JavaScript code is being parsed and executed.
The type of execution context
There are three types of execution contexts
-
Global execution context: there is only one. The global object in the browser is the Window object. This points to this global object.
-
Function execution contexts: There are an infinite number of them, which are created only when a function is called, and a new execution context is created each time a function is called.
-
Eval function execution context: Refers to code that runs in the Eval function, rarely used and not recommended.
Execution stack
The execution stack, also known as the call stack, has a LIFO (Last in, first out) structure for storing all execution contexts created during code execution.
When JS code is first run, a global execution context is created and pushed into the current execution stack. Each time a function call occurs, the engine creates a new function execution context for that function and pushes it to the top of the current execution stack.
According to the execution stack LIFO rule, when the top function is completed, its corresponding function execution context will Pop out of the execution stack, and the control of the context will be moved to the next execution context of the current execution stack.
var a = 'Hello World! ';
function first() {
console.log('Inside first function');
second();
console.log('Again inside first function');
}
function second() {
console.log('Inside second function');
}
first();
console.log('Inside Global Execution Context');
// Inside first function
// Inside second function
// Again inside first function
// Inside Global Execution Context
Copy the code
Create the execution context
The execution context is created in two stages: 1) the create stage; 2) Execution phase
Create a stage
-
1. Determine the value of this, also known as this Binding.
-
2. The LexicalEnvironment component is created.
-
3. The VariableEnvironment component is created.
It might be more intuitive to look at the pseudocode directly
ExecutionContext = {
ThisBinding = <this value>// Make sure this LexicalEnvironment = {... }, // lexical environment VariableEnvironment = {... }, // Variable environment}Copy the code
This Binding
-
In the global execution context, the value of this points to the global object, in the browser to the window object, and in nodeJS to the module object of the file.
-
In the context of function execution, the value of this depends on how the function is called. There are default binding, implicit binding, explicit binding (hard binding), new binding, and arrow functions, which are explained in this section.
Lexical Environment
The lexical environment has two components
-
1. Environment record: Store the actual location of variable and function declarations
-
2, reference to the external environment: you can access its external lexical environment
There are two types of lexical environments
-
Global environment: is a lexical environment with no external environment, whose external environment reference is NULL. The value of this refers to a global object (window object) with its associated methods and properties (such as array methods) and any user-defined global variables.
-
Function environment: Variables defined by the user in a function are stored in the environment record, which contains arguments objects. A reference to an external environment can be a global environment or an external function environment that contains internal functions.
It might be more intuitive to look at the pseudocode directly
GlobalExectionContext = { // Global execution context
LexicalEnvironment: { // lexical context
EnvironmentRecord: { // Environment record
Type: "Object".// Global environment
// The identifier is bound here
outer: <null> // A reference to the external environment
}
}
FunctionExectionContext = { // Function execution context
LexicalEnvironment: { // lexical context
EnvironmentRecord: { // Environment record
Type: "Declarative".// Function environment
// The identifier is bound here // a reference to the external environment
outer: <Global or outer function environment reference>}}Copy the code
The variable environment
The variable environment is also a lexical environment, so it has all the attributes of the lexical environment defined above.
In ES6, the difference between lexical and variable environments is that the former is used to store ** function declarations and variable (let and const) bindings, while the latter is only used to store variable (var) ** bindings.
Use examples to introduce
let a = 20;
const b = 30;
var c;
function multiply(e, f) {
var g = 20;
return e * f * g;
}
c = multiply(20.30);
Copy the code
The execution context is shown below
GlobalExectionContext = {
ThisBinding: <Global Object>, LexicalEnvironment: {EnvironmentRecord: {Type: "Object", // the identifier is binding here < uninitialized >, multiply: < func > } outer: <null> }, VariableEnvironment: { EnvironmentRecord: { Type: C: undefined,} outer: <null>}} FunctionExectionContext = {ThisBinding: <Global Object>, LexicalEnvironment: {EnvironmentRecord: {Type: "Declarative", // 30, length: 2}, }, outer: <GlobalLexicalEnvironment> }, VariableEnvironment: { EnvironmentRecord: { Type: G: undefined, outer: <GlobalLexicalEnvironment>}}Copy the code
Why variables are promoted: During the creation phase, function declarations are stored in the environment and variables are set to undefined (in the case of var) or remain uninitialized (in the case of let and const). So this is why it is possible to access variables defined by var (albeit undefined) before the declaration, but if you access variables defined by let and const before the declaration, you will be prompted with reference errors. This is called variable lifting.
Execution phase
At this stage, all variables are assigned and the code is executed.
If the Javascript engine cannot find the value of the let variable at the actual location declared in the source code, it will be assigned a undefined value.
reference
Understand Javascript execution context and execution stack