Today, I sorted out the JS knowledge points again, and then found an UP master’s explanation in B station, which was very useful, so I made notes and sorted it out

Resources refer to JS execution context and scope

Execution context

Before executing a statement, JS creates an execution context for code execution, in which a text environment is used to store variable names, function names, class names, and so on

Execution stack

The execution stack is a place where the execution context is stored. It is a first-in, last-out queue

  • Execution stack The execution context on top of the stack is called the current execution context
  • Resources needed in the JS code will be looked up in the current execution context

Create execution context

  • Access global code
  • Enter the function body code
  • Enter the code specified by the eval function argument
  • Enter the Moduled code

The following two examples will help

3.1

console.log(foo);
if(false) {var foo = 'foo';
}
/ / output is undefined
Copy the code
  • Step1:

    First, a global execution context is created and added to the top of the stack. The current execution context is the global execution context

    The text environment of a global execution context consists of two parts: a global object and a global scope

    • Global object: In the browser, the window object, var and function variables declared in the global object
    • Global scope: Let, const, and class variables are declared in the global scope
    • JS code in the execution of the process to find a variable, first to the global scope to find, and then to the global object to find
  • Step2:

    • Find all non-function var declarations;
    • Find all top-level function declarations;
    • Find top-level let, const, and class declarations;
    • Find the block declaration, variable name does not repeat the above, if repeated block declaration does not do
  • Step3: Name repeat processing:

    • The names of the let, const, and class declarations cannot be repeated
    • The let, const, class and var/function names must not be the same
    • Var and function declare the same name, function declare the function name precedence
  • Step4: create a binding

    • Registers and initializes var as undefined
    • Top-level function declaration: Registers the function name and initializes it as the newly created function object
    • Function declaration at block level: register name, initialize to undefined
    • Let, const, class, but not initialized
  • Step5: Execute the statement

3.2

var a = 10
function foo(){
    console.log(a)
    let a }
foo()
// Cannot access 'a' before initialization
Copy the code
  • Step1: create a global execution context and add it to the top of the stack

  • Step2: Find var declaration a, function declaration foo

  • Step3: Repeat the name processing

  • Step4: create variables:

    • Initialize a to undefined,a:undefined
    • Register and initialize Foo,foo:objAt this point, the function object will hold the text environment of the execution context when the function was created
  • Execute statement:

    • Assign 10 to a;
    • Function call:
      • Create an execution context for function foo and add it to the top of the stack. Its text context is the text part of the execution context when the function is created
      • Find the let declaration, create the variable, register a of the let declaration, but do not initialize
      • Execute statement, result Cannot access 'a' before initialization

Block-level scope

A scope is a collection of parsed lookup variable names, which is the current execution context (or the text context of the current execution context)

  • The global scope is the global execution context
  • A function scope is the execution context of a function, which is determined when the function is created, not called
function foo(){
    console.log(a)
}
function bar(){
    var a = 3;
    foo();
}
var a = 2;
bar()
// Output: 2
Copy the code

4.1

console.log(foo);
if(true) {function foo(){
        console.log('in block')
    }
}
foo();
// Output: undefined in block
Copy the code

Step1: create a global execution context and add it to the top of the stack

Step2: Find foo declared in the block

Step3: create foo in the global object and initialize undefined

Step4: execute the statement console.log(foo) and the if statement

  • When console.log(foo) is executed,foo simply declares that it is undefined

  • Execute if statement:

    • Create a text environment for the if block and link to the original text environment

    • Find the function declaration inside the block

    • Creates foo in the block’s text environment and initializes it as a function object

    • When the if statement is executed, the text environment is linked back to the original text environment, and the global object is checked to see if there is a variable named foo, and if so, the foo in the block is replaced with foo in the global object

  • Execute foo() to print out in block

4.2

var liList = []
for (var i=0; i<5; i++){ liList[i] =function(){
        console.log(i)
    }
}
liList[0]()
liList[1]()
liList[2]()
liList[3]()
liList[4] ()//5
Copy the code

Step1: create the global context and place it at the top of the stack

Step2: Find the liList and I of the var declaration

Step3: Define and initialize liList and I as undefined

Step4: Execute the statement

  • LiList is an empty array and 0 is assigned to I (I =0 in the global object)

  • Judge I < 5

  • Execute the for block statement:

    • Create a text environment and connect to the text environment of the global context (I =0)
    • Execute the function expression function, create a function object of liList[0], and assign liList[0] to liList[0] in the global object at the end of a loop.
    • I ++, I = 1, I <5, continue to execute the code block statement for, create a new text environment, link to the global execution context of the text environment, create liList[1] function object, etc. At the end of the liList[1] assigned to the global object liList[1]… I ends up being equal to 5 in the global object
    • After all loops are completed, the text environment of the global execution context is re-linked to the original text environment.
  • Execute a function call:

    • Create the function execution context
    • The text environment of the function execution context is linked to the text environment stored in its own body, which is the text environment in which the function object was created
    • Go to the global objectiAnd prints

4.3

var liList = []
for (let i=0; i<5; i++){ liList[i] =function(){
        console.log(i)
    }
}
liList[0]()
liList[1]()
liList[2]()
liList[3]()
liList[4] ()// 0 1 2 3 4 
Copy the code

Step1: create the global context and place it at the top of the stack

Step2: Find the liList declared by var

Step3: Define and initialize liList as undefined

Step4: Execute the statement

  • LiList is an empty array

  • Create a text environment, link to the original text environment, and execute the let declaration and assignment (I =0).

  • It also creates a new text environment, copies I =0 into the new text environment, and links to the global context’s text environment

  • Judge I < 5

  • Execute the for block statement:

    • Create a text environment and link to the text environment of the global context

  • Execute the function expression function, create a function object of liList[0], and assign liList[0] to liList[0] in the global object at the end of a loop.

  • After executing a loop, duplicate it againIterative text environment,i=0Copy to it and link to the global execution context, execute i++, and judgei<5To continue executing the code block

  • When the loop is complete, the link is re-linked to the original text environment

  • Execute a function call:

    • Create a function execution context. The text context of the function execution context is linked to the text environment stored in the function body

    • Go to the text environment saved in the function body and find I, and print it