In depth explanation of Javascript execution context order

  • 2021-09-12 00:06:54
  • OfStack

1 execution context?

1 What is the execution context?

The execution context is an abstraction of the environment in which the current JavaScript code is parsed and executed, and any code running in JavaScript is run in the execution context.

2 Type of execution context

There are three types of execution contexts:

Global execution context: There is only one, which is the default and basic execution context. (Code that is not in any function is a global execution context.) It has two functions, one is to create a global variable, that is, to point to the variable under window, and the other is to point the this to the global.

Function execution context: There are countless, each function has its own execution context, but it is created only when the function is called, and a new execution context is created for the function every time it is called …

Eval Function Execution Context: Refers to code running in an eval function and is rarely and not recommended.

2 Life cycle of execution context

1. Create phase

There are three phases in the life cycle of an execution context: the creation phase, the execution phase, and the recycle phase (mainly the creation phase)

When a function is called without executing any of its internal code, these three steps are determined first:

1) Create a variable object: First initialize the function parameter arguments, and promote the function declaration and variable declaration
2) Creating a scope chain: During the creation phase of the run-time context, the scope chain is created after the variable object. The scope chain itself contains the variable object.
Scope chains are used to resolve variables. When asked to resolve variables, JavaScript always starts at the innermost level of code nesting, if the innermost level does not have
When a variable is found, it jumps to the parent scope of the next level until it is found.
3) Determine the this direction: There are many cases.

2. Implementation phase

Perform variable assignment, code execution

3. Recovery phase

Execution context out of stack waiting for virtual machine to reclaim execution context

3. Variable promotion and this pointing

1. Variable declaration promotion:

Most programming languages declare variables before using them, but in JS, things are somewhat different:


console.log(a); // undefined
var a = 10;

The above code normally outputs undefined instead of reporting an error Uncaught ReferenceError: a is not defined because of the declaration promotion.
Equivalent to:


var a; // Declaration   The default value is undefined  [Preparations] 
console.log(a);
a = 10; // Assignment 

2. Function declaration promotion

There are two ways to create a function. One is to declare function aa () {} through the function

The other is through the function expression var aa = function () {}, so what is the difference between these two in function promotion?


console.log(f1); // function f1(){}
function f1() {} //  Function declaration 
console.log(f2); // undefined
var f2 = function() {}; //  Function expression 

Next, let's illustrate this problem with an example:


function test() {
 aa(); // Uncaught TypeError "aa is not a function"
 bar(); // "this will run!"
 var aa = function() {
  // function expression assigned to local variable 'aa'
  alert("this won't run!");
 };
 function bar() {
  // function declaration, given the name 'bar'
  alert("this will run!");
 }
}
test();

In the above example, an error was reported when aa () was called, while bar was called normally.

As we said earlier, both variables and functions will rise. When the function expression var aa = function () {}, var aa will first rise to the top of the function body. However, the value of aa at this time is undefined, so aa () will report an error.

For the function bar (), the whole function is promoted, so bar () can be executed smoothly.

Details must be noted: When a function and a variable have the same name and are both promoted, the function declaration takes higher priority, so the variable declaration will be overwritten by the function declaration, but the value can be reassigned.


alert(a); // Output: function a(){ alert(' I am a function ') }
function a() {
 alert(" I am a function ");
} //
var a = " I am a variable ";
alert(a); // Output: ' I am a variable '

The function declaration takes precedence over the var declaration, which means that the function declaration overrides the var declaration when two variables with the same name are declared by function and var at the same time
This code is equivalent to:


function a() {
 alert(" I am a function ");
}
var a; //hoisting
alert(a); // Output: function a(){ alert(' I am a function ') }
a = " I am a variable "; // Assignment 
alert(a); // Output: ' I am a variable '

3. Determine this pointing


//  Situation 1
function foo() {
 console.log(this.a) //1
}
var a = 1
foo() // this->window
//  Situation 2
function fn(){
 console.log(this);
}
var obj={fn:fn};
obj.fn(); //this->obj

//  Situation 3
function CreateJsPerson(name,age){
//this Is the current class's 1 Instances p1
this.name=name; //=>p1.name=name
this.age=age; //=>p1.age=age
}
var p1=new CreateJsPerson(" Yin Huazhi ",48);

//  Situation 4
function add(c, d){
 return this.a + this.b + c + d;
}
var o = {a:1, b:3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

//  Situation 5
<button id="btn1"> Arrow function this</button>
<script type="text/javascript">
 let btn1 = document.getElementById('btn1');
 let obj = {
  name: 'kobe',
  age: 39,
  getName: function () {
   btn1.onclick = () => {
    console.log(this);//obj
   };
  }
 };
 obj.getName();
</script>

Results:

1 this points to window;

2 Whoever calls the function is this, so the this in the foo function in this scenario is the obj object

In the constructor, this is an instance of the current class

4call, apply, and bind: this is the first parameter

5 The arrow function this points to: The arrow function does not have its own this, see if there is a function in its outer layer. If there is, the this of the outer function is the this of the inner arrow function, and if there is no, this is window.


Related articles: