JavaScript precompilation and scoping

The JavaScript precompilation process and scoping analysis steps are an important part of JS learning and can help us understand the order in which code is executed and the concept of closures.

precompile

  1. JavaScript Execution Steps

    Check for grammatical errors throughout the text - > precompilation - > explain execution

  2. Implicit global variables

    Variable does not declare direct assignment and is mounted under a window object

    a = 1;
    console.log(a); // 1
    
    function test() {
        var b = c = 1;
    }
    test();
    console.log(c); // Print 1, c undeclared, assign directly, imply global variable
    console.log(window.b); // Undefined, no property exists on the print object, returns undefined
    console.log(b); // Report errors
  3. Precompilation process

    Function declaration overall promotion

    Variable declarations are promoted, assignments are not promoted

    test(); // Put first to execute
    function test() {
    
    }
    console.log(a); // Print out undefined
    var a = 1; // Declarations are promoted, assignments are not promoted

GO

  1. global object, global context, that is, window object

  2. Generate GO, that is, variable declaration promotion and function declaration promotion, immediately before global execution

  3. Step: Find variable declaration - > Find function declaration - > Sequential execution

    var a = 1; // (1)
    function a() {
        console.log(2);
    }
    console.log(a); // (2)
    // Global precompilation
    // Variable declaration a -> GO {a: undefined} 
    // Function declaration a (){} -> GO {a: a (){}} 
    // Global Execution
    // Execution (1) -> GO{a: 1}
    // Execute (2), print 1
    console.log(a); // (1)
    var a = 1; // (2)
    console.log(a); // (3)
    function a() {
       console.log(2);
    }
    // Global precompilation
    // Variable declaration a -> GO {a: undefined} 
    // Function declaration a (){} -> GO {a: a (){}}
    // Global Execution
    // Execute (1), print a(){...}
    // Execution (2) -> GO{a: 1}
    // Execute (3), print 1

AO

  1. activation object, function context, that is, active object

  2. Each function has its own AO, which is generated immediately before execution and destroyed after execution

  3. Step: Find formal and variable declarations - > formal and parameter mappings - > Find function declarations - > sequential execution

  4. Note: AO has var a declaration and will not look for a in GO

    function test(a) {
        console.log(a); // (1)
        var a = 1; // (2)
        console.log(a); // (3)
        function a() {}
        console.log(a); // (4)
        var b = function() {} // (5)
        console.log(b); // (6)
        function d() {}
    }
    test(2); 
    // Global precompilation
    // Function declaration test(){} -> GO{a: test(){}} 
    // Global Execution
    // Execute to test(2), function test precompiled
    // Variable declaration a, B -> test_AO{a: undefined, b: undefined}
    // Parameter Mapping-> test_AO{a: 2, b: undefined}
    // Function declaration - > test_AO{a:a(){}, b:undefined, d:d(){}
    // Function test execution
    // Execute (1), print a(){}
    // Execute (2) -> test_AO{a:1, b: undefined, d: d(){}}
    // Execute (3), print 1
    // Execute (4), print 1
    // Execute (5) -> test_AO{a:1, b: (){}, d: D (){}}
    // Execute (6), print (){}
    // Function test finished executing, test_AO destroyed
  5. Practice

    a = 1; // (1)
    function test() {
        console.log(a); // (2)
        a = 2; // (3)
        console.log(a); // (4)
        if(a) { // (5) Pre-compile without looking at if because the sentence was not executed
            var a = 3; 
        }
        console.log(a); // (6)
    }
    test();
    var a;
    // Global precompilation
    // Variable declaration, function declaration - > GO{a: undefined, test: test(){}}
    // Global Execution
    // Execute (1) -> GO{a:1, test: test(){}}
    // Execute to test(), function test precompiled
    // Variable declaration - > test_AO{a: undefined}
    // Function test execution
    // Execute (2), print undefined
    // Execution (3) -> AO {a: 2}
    // Execute (4), print 2
    // Execution (5) -> AO {a: 3}
    // Execute (6) ->Print 3
    // Function test finished executing, test_AO destroyed

Scope

  1. Properties of functions

    A function is a reference type

    There are some native attributes that can be used, and some that are not accessible, which are implicit attributes inherent in the js engine

    [[scope]] is the implicit property inside the JS and is the container where the function stores the scope chain

    function test() {
    
    }
    console.log(test.name); // test
    console.log(test.length); // 0
  2. Scope Chain

    When a function is declared, an implicit JS internal property [[scope]] is generated, the 0th bit of which holds a reference to the global execution period context GO

    Shortly before the function executes, [[scope]] position 0 holds the function execution context AO, the next holds the outer function AO, and finally saves the GO reference.If there is no outer function, then AO number 0, GO number 1.When looking for declarations, they all look backwards by 0 digits, that is, look at yourself first, then at the outer layer, and finally at the global situation

    Destroy AO from [[scope]] at the end of function execution

    function a() {
        funtion b() {
            var b = 2; // (3)
        }
        var a = 1; // (2)
        b(); 
    }
    var c = 3; // (1)
    a();
    // Global precompilation
    // -> GO{c: undefined, a: a(){}}
    // -> a.SCOPE = [
    //               GO{c: undefined, a: a(){}}
    //       ]
    // Global Execution
    // Execution (1)
    // -> GO{c: 3, z a(){}}
    // -> a.SCOPE = [
    //               GO{c: 3, a: a(){}}
    //       ]
    // Execute to a(), function a precompiled
    // -> a.SCOPE = [
    //               a_AO{a: undefined, b: b(){}}, 
    //               GO{c: 3, a: a(){}}
    //       ]
    // -> b.SCOPE = [
    //               a_AO{a: undefined, b: b(){}}, 
    //               GO{c: 3, a: a(){}}
    //       ]
    // Function a Execution
    // Execution (2)
    // -> a.SCOPE = [
    //               a_AO{a: 1, b: b(){}}, 
    //               GO{c: 3, a: a(){}}
    //       ]
    // Execute to b(), function B precompiled
    // -> b.SCOPE = [
    //               b_AO{b: undefined}, 
    //               a_AO{a: 1, b: b(){}}, 
    //               GO{c: 3, a: a(){}}
    //       ]
    // Execution (3)
    // -> b.SCOPE = [
    //               b_AO{b: 3}, 
    //               a_AO{a: 1, b: b(){}}, 
    //               GO{c: 3, a: a(){}}
    //       ]
    // Function B is executed and b_AO is destroyed
    // -> b.SCOPE = [
    //               a_AO{a: 1, b: b(){}}, 
    //               GO{c: 3, a: a(){}}
    //       ]
    // Function A is executed, a_AO is destroyed
    // -> b.SCOPE Destroy
    // -> a.SCOPE = [
    //               GO{c: 3, a: a(){}}
    //       ]

Tags: Javascript

Posted on Tue, 17 Mar 2020 18:49:30 -0700 by Emir