Execution context and execution context stack

1. Variable promotion and function promotion

①Variable  declaration promotion : Variables defined (declared) through var can be accessed before the definition statement , and the value is undefined ;
②Function  declaration promotion : Functions declared through function can be called directly before, value: function definition ( object)

1.1 Code experience

<script>
    /* 经典面试题 */
    var a = 3;
    function fn() {
        console.log(a);
        var a = 4
    };
    fn();
    // 问:输出结果是什么?
    // 答:输出 undefined
    /* 分析:上述代码实际运行顺序如下: */
    var a;
    a = 3;
    function fn() {
        var a;
        console.log(a);  // 此时根据就近原则输出a的值,而a只声明未赋值,所以为undefined
        a = 4;
    };
    fn();

    /* 体验变量声明提升和函数声明提升的作用 */
    console.log(b);   // undefined,未定义前可访问到,变量提升
    fn2() // 可调用, 存在函数提升
    fn3()  // 不可调用,只是存在变量提升,没有函数提升
    var b=3;
    function fn2(){
        console.log('fn2()');
    };
    var fn3=function(){
        console.log('fn3()');
    };
</script>

Note : Only functions declared through function have the promotion function . Function expressions set through assignment operations do not. They can only be called after the function is declared. For example, function fn3 in the above code cannot be called before.

So here comes the question: How do variable promotion and function promotion come about ? This involves knowledge about execution context ...

2. Execution context

JS code can be divided into: global code and function (local) code according to location. Therefore, the execution context is divided into global execution context and function execution context.

2.1 Global execution context

Before executing the global code , determine the window as the global execution context
② Preprocess (pre-parse) the global data:

  1) Global variables defined by var ==> undefined, added as attributes of window
  2) Global functions declared by function ==> assignment (fun), added as methods of window
  3) this ==> assignment (window)

③ Start executing global code

2.2 Function execution context

Before calling the function and preparing to execute the function body , create the corresponding function execution context object (virtual, existing in the stack)
② Preprocess (pre-parse) the local data:

  1) Formal parameter variable ==> Assignment (actual parameter) ==> Added as an attribute of the execution context
  2) Arguments ==> Assignment (actual parameter list), added as an attribute of the execution context
  3) Local variables defined by var == > undefined, added as an attribute of the execution context
  2) Function declared by function ==>Assignment (fun), added as a method of the execution context
  3) this==>Assignment (the object of the calling function)

③ Start executing the function body code

2.3 Code experience

<script>
    // 1. 全局执行上下文--window
    console.log(a1); // undefined
    console.log(window.a1); // // undefined
    console.log(a1 === window.a1); // true,说明全局执行上下文window对var定义的变量a1进行了预处理,将其添加为它的属性
    a2(); // a2()调用成功
    console.log(a2() === window.a2()); //true,说明把function声明的函数a2添加为window的方法
    console.log(this); // window对象,对this赋值

    var a1 = 3;
    function a2() {
        console.log('a2()调用成功');
    };
    console.log(a1); // 3, 开始执行全局代码之后,此时的a1被赋值为3,当然其依旧为window的属性

    // 2. 函数执行上下文
    function fn(a1) {
        // 预处理阶段是在调用函数后,执行函数体前进行
        console.log(a1); // 2,把实参的值赋给形参
        console.log(a2);  // undefined,var定义的局部变量a2添加为执行上下文的属性
        a3(); // a3()调用成功
        console.log(this);  // window,因为此函数是直接调用的,所以调用者为window
        console.log(arguments);  // 伪数组[2,3]
        
        var a2 = 4;
        function a3() {
            console.log('a3()调用成功');
        };
    };
    fn(2, 3);
</script>

3. Execution context stack

Before the global code is executed , the JS engine will create a stack to store and manage all execution context objects ;
② After the global execution context (window) is determined, it is added to the stack (push), and the window is always placed on the stack. ③ After the function execution context
is created, add it to the stack (push)
④ After the current function is executed, remove the object on the top of the stack (pop it)
③ When all the code is executed, the stack Only window is left in

 3.1 Code experience

<script>
                            // 1. 进入全局执行上下文
    var a = 10;
    var bar = function(x) {
        var b = 5;
        foo(x + b);       // 3. 进入foo函数执行上下文
    };
    var foo = function(y) {
        var c = 5;
        console.log(a + c + y);
    };
    bar(10);              // 2. 进入bar函数执行上下文
</script>

Execution sequence diagram in execution context stack:

Notice:

① Every time a function is called, the execution context object that generates this function will correspond;

② After the function finishes executing the function body code, it will be destroyed, that is, it will disappear from the memory, and it will no longer exist in the context execution stack, that is, it will be popped out of the stack.

Guess you like

Origin blog.csdn.net/JJ_Smilewang/article/details/125696100