This is the third day of my participation in the August More Text Challenge. For details, see “August More Text Challenge”.

preface

JavaScript execution includes compilation phase and execution phase. After compilation, the execution context is obtained and the executable code is obtained. The execution phase maintains the execution context stack (call stack). In this paper, we have a deeper understanding of the execution process of JavaScipt through the specific details of the execution context.

Train of thought

1. Clarify the relationship between variables, execution context, execution context stack and scope chain in the execution process

2. Perform context supplement

3. Block-level scope introduced by ES6

PS: The concept of block-level scope was introduced in ES6. To avoid confusion, the concept of block-level scope is not considered here. JavaScript itself was designed with no block-level scope, and the logic would be messy if you tried to force it all together. (Just give me the whole won’t. Some comb down, or separate is better.

JavaScript execution process comb

Static scope: global scope, function scope, block-level scope (not considered yet)

Global scope: Objects in global scope can be accessed from anywhere in the code, and their lifetime follows the lifetime of the page.

Function scope: A function scope is a variable or function defined inside a function, and the defined variable or function can only be accessed inside the function. At the end of function execution, variables defined inside the function are destroyed.

JavaScript itself is statically scoped, independent of the runtime. The context in which the function is called is defined, and no matter how you call the function, the variables in the function will not change depending on the order in which the call is made. (The same variable, this will change)

For example

Var a = 10; function fn() { var b = 1; console.log(a + b); } fn(); / / 11Copy the code

Intuitive feeling:

After the compile phase, global execution context, FN execution context, executable code

The code is executed, and the global execution context is pushed onto the stack (at this point the variable a in the global execution context has been created and initialized to undefined, which was done at compile time, and is simply put on the call stack).

If a=10 is assigned, the function fn is called, and fn’s execution context is pushed (the variable b in fn’s execution context, created and initialized as undefined).

Assign b=1, console.log(a+b), compute a+b, and execute the function call

In this case, the variable a does not appear in the fn execution context, that is, the parent scope is searched (recursively) until the global scope is reached.

The important point here is that the parent scope is not the previous execution context in the execution context stack, but the context to which the outer pointer in the current execution context points. Because the outer pointer points to the global context (because JavaScript is statically scoped, at compile time, the parent scope outer is determined only by the nesting of functions in the code), the global context has the variable a being 10.

Then execute the console.log function call, after the completion of the stack.

// Scope: function foo() {console.log(a); } function bar() { var a = 3; foo(); } var a = 2; bar(); / / 2;Copy the code

Intuitive feeling:

The outer of the foo execution context is the global context

The outer of the bar execution context is the global context

So when foo is called, there is no variable a in the execution context of foo, so it goes to the parent scope, the outer pointer points to the variable area in the global context to look for variable a, which has a value of 2

The execution context stack is foo execution context (top), bar execution context (bottom), and global execution context (bottom).

Note: The scope chain is independent of the stack of execution contexts, but is concerned with the nesting of function declarations in the code (in JavaScript!).

Execution context

Variable environment Related variables in the current execution context

The lexical environment corresponds to the block-level scope introduced in ES6

Outer points to the parent execution context and the outer of the global execution context is NULL

This (skip this for clarity, stay tuned)

Block level scope let const

Introduction to the

Block-level scope. Intuitively, a statement block (a piece of code wrapped in {}) is a block-level scope.

Using the var keyword declare variables is the global scope, or function scope, ES6 in the function scope on the basis of added a block-level scope, is essentially in the execution context added lexical environment such a stack structure, to save each scope block (block) (scope block contains the grammar in the use of the let statement variables).

Function foo(){var a = 1 let b = 2 {let b = 3 var c = 4 let d = 5 console.log(a) console.log(b)} console.log(b) console.log(c) console.log(d) } foo()Copy the code

Again, the essence of javaScript execution is represented by the execution context

When executed to the block-level scope, variables declared as lets and const in the block-level scope are appended to the lexical environment. When the block finishes executing, the contents appended to the lexical scope are destroyed.

阿鲁纳恰尔邦

阿鲁纳恰尔邦

阿鲁纳恰尔邦

阿鲁纳恰尔邦

阿鲁纳恰尔邦

阿鲁纳恰尔邦

This example is just to deepen the understanding of lexical environment, the next to enter my most muddled knowledge point, variable improvement.

Variable improvement progression (temporary dead zone progression)

// Case 0 let myname= 'geek time' {console.log(myname)} // Print very correctly find order lexical environment stack top -> lexical environment stack bottom -> variable environment -> upper level execution context up to global execution context // Case 1 let {console.log(myname) let myname= 'geek state'}Copy the code

“Create, initialize, and assign” for JS variables

What we call a variable declaration actually involves the creation and initialization of the variable to undefined.

Var var = create; initialize = initialize;

Let, the const variable, is also promoted, only create is promoted.

Important reference www.jianshu.com/p/0f49c88cf…

The introduction of let const solves two problems: avoid declaring the same variable more than once, and destroy the variable in time at the block level scope.

PS: So far the investigation of JavaScript execution process has come to an end, the execution context is the thread throughout. Follow-up to this pointer related content complement, it is time to embark on a new journey. Talk about the object, especially want a new object, ha ha.