Update your knowledge, build on the past and embrace the future.

concept

Look directly at the definition of ExecutionContext:

An execution context is a specification device that is used to track the runtime evaluation of code by an ECMAScript implementation.

ExecutionContext is an abstract concept that describes the execution environment of executable code. Executable code runs in an ExecutionContext.

Management styleExecutionContextStack

Execution Context Stack is a LIFO Stack structure. The running Execution context is always at the top of the stack. When control is transferred from the current execution context to another executable, the execution context is created and pushed to the top of the stack. At the end of execution, the execution context is ejected from the top.

Ponder: WhatECMAScriptFeatures will makeExecution context stackDon’t followLIFOThe rules?

The specification states:

Transition of the running execution context status among execution contexts usually occurs in stack-like last-in/first-out manner. However, some ECMAScript features require non-LIFO transitions of the running execution context.

However, some ECMAScript features are not found in the spec. But first, does Generator count? Execution Context Stack. Violation of the LIFO order using Generator Function

function *gen() {
  yield 1;
  return 2;
}

let g = gen();

console.log(g.next().value);
console.log(g.next().value);
Copy the code

When a function is called, the execution of the current execution context is suspended. The execution context of the called function is created and pushed to the top of the stack. When the function returns, the execution context of the function is destroyed and the execution of the suspended execution context is resumed.

Now, with Generator, the Execution context of the Generator function remains after it returns the value of the yield expression. It is not destroyed, but is suspended and handed over control, and may resume execution at some point.

Is it? To be proved.

Lexical environmentLexical Environments

Look at the specification definition:

A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upon the lexical nesting structure of ECMAScript code.

By spec, the Lexical Environment defines the mapping of identifying identifiers to Variables or Functions.

compositionLexical EnvironmentContains two parts:

  • Environment Record

Document the mapping of the created identity identifiers to Variables or Functions

type The paper
Declarative Environment Records recordvar,const,let,class,import,functionSuch a statement
Object Environment Records To bind to an object and record in that objectstring identifierAttribute of, notstring identifierThe properties of the.Object environment recordsforwithStatement created
Function Environment Records Declarative Environment RecordsFor the top layer of a function, provided in the case of a non-arrow functionthis, if also referencedsuperprovidessuperMethod binding
Global Environment Records Contains all top-level declarations andglobal objectThe properties of theDeclarative Environment RecordswithObject Environment RecordsThe combination of
Module Environment Records Declarative Environment RecordsUsed ofES moduleIn addition to constant and variable declarations, contains immutableimportThe binding provided to anotherenvironment recordsIndirect access to
  • externalLexical EnvironmentA reference to the

Nested structures are formed by references, which may be null

classificationLexical EnvironmentIn three categories:

  • Global Environment

Lexical Environment without external Lexical Environment

  • Module Environment

Contains the module’s top-level declaration as well as the import declaration, and the external Lexical Environment is the Global Environment

  • Function Environment

Corresponding to functions in JavaScript, it establishes the binding of this and the necessary binding of the super method

The variable environmentVariable Environments

Before ES6, variables were declared by var. After ES6, variables were declared by let and const. To be compatible with VAR, Variable Environments were used to store variables declared by var.

Variable Environments is essentially Lexical Environments

mechanism

For details, see the ECMAScript 2019 Language Specification. Related is at 8.3 Execution Contexts.

Understanding Execution Context and Execution Stack in Javascript

See the examples below:

var a = 20;
var b = 40;
let c = 60;

function foo(d, e) {
    var f = 80;
    
    return d + e + f;
}

c = foo(a, b);
Copy the code

Create an Execution Context like this:

GlobalExecutionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Object".c: < uninitialized >,
      foo: < func >
    }
    outer: <null>,
    ThisBinding: <Global Object>
  },
  VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // Identifier bindings go here
      a: undefined,
      b: undefined,
    }
    outer: <null>, 
    ThisBinding: <Global Object>
  }
}
Copy the code

At run time, variable assignment is complete. So GlobalExecutionContext at execution time looks something like this:

GlobalExecutionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Object".c: 60.foo: < func >,
    }
    outer: <null>,
    ThisBinding: <Global Object>
  },
  VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // Identifier bindings go here
      a: 20,
      b: 40,
    }
    outer: <null>, 
    ThisBinding: <Global Object>
  }
}
Copy the code

When a call to function foo(a, b) is encountered, a new FunctionExecutionContext is created and executes the code in the function. In the creation phase it looks like this:

FunctionExecutionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative".Arguments: {0: 20.1: 40.length: 2}},outer: <GlobalLexicalEnvironment>,
    ThisBinding: <Global Object or undefined>,
  },
  VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      f: undefined
    },
    outer: <GlobalLexicalEnvironment>,
    ThisBinding: <Global Object or undefined>,
  }
}
Copy the code

When executed, it looks like this:

FunctionExecutionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative".Arguments: {0: 20.1: 40.length: 2}},outer: <GlobalLexicalEnvironment>,
    ThisBinding: <Global Object or undefined>,
  },
  VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      f: 80
    },
    outer: <GlobalLexicalEnvironment>,
    ThisBinding: <Global Object or undefined>,
  }
}
Copy the code

After the function completes, the return value is stored in C. So GlobalExecutionContext is updated. After this, the code execution is complete and the program is terminated.

conclusion

The ECMAScript specification is updated every year, so we need to learn more about it, based on the past and the present, and embrace the future!

The resources

  1. All functions are closures: on scope and Closure in JS
  2. JS compacting the execution context and lexical environment
  3. Take a look at Execution Contexts and Lexical Environments in conjunction with the JavaScript specification
  4. You-Dont-Know-JS 2nd-ed
  5. ECMAScript 2019 Language Specification
  6. Understanding Execution Context and Execution Stack in Javascript