1

The JavaScript engine performs the following operations before the code is executed:

  1. First performed word / sentence lexical analysis is divided into lexical units token , after the entire scope of the current analysis is complete, JS engine will token be parsing / syntax analysis translated into AST (abstract syntax tree)
  2. precompile (preprocess)
  3. Execute while interpreting (not pure interpretation, but also JIT compilation, which will not be expanded here)

precompile (preprocess)

Some people say that JavaScript is not precompiled, it is a part of syntax analysis, some people say that there is lexical, grammar and code generation are already compiled, but it does not need to be compiled in advance, but is compiled a few milliseconds before execution. So whether JavaScript is precompiled or whether these steps belong to precompilation (preprocessing), the opinions of the big guys are also different, we will not discuss it, for the time being, some processing processes after the syntax analysis generates AST and before execution are called "precompiled" put.

  1. global precompile

    1. Create Global Object global context object
    2. Find the variable declaration and bind the variable name as GO with a value of undefined
    3. Find function declarations, function name will bind to GO a property value of function body
    4. execute global code
  2. partial precompile

    1. Create Activation Object function context object
    2. Find the reference line, the line parameter name binding for AO a property, the value of undefined
    3. Find variable declaration, the variable name to bind to AO a property, the value of undefined
    4. Assign the actual parameter value to the formal parameter
    5. Find function declarations, function name will bind to AO a property value of function body
    6. The function generates [[scope]] attribute, the value is an array, the first item of the array is the AO of this function, the next item is the AO of the outer function, and it goes all the way to the outer layer until the last item is GO
    7. execute function code

Declarative hoisting, scope chain

The first half of the precompiled part above is the so-called declaration promotion. I have an article about the declaration promotion separately, so I won't go into details. For click here

函数执行前会生成`[[scope]]`属性,值为一个数组,数组的第一项是本函数的 AO
下一项为外层函数的 AO,一直往外层,直到最后一项为 GO

AO is the scope of a function, and [[scope]] this chain array is a function of the scope chain, when the function the value of the RHS will first query in [[scope]] looking for in the first term, if not found then search for the second layer , and so on until a GO is found.

Closure

When the function FN ends, the life cycle of the AO function FN should end and needs to be destroyed. But there are special circumstances, although that is a special case, but the development is very common, it is after the FN function execution return a internal function A and the external storage, which should be destroyed function of FN AO can not be destroyed because the function a [[scope]] preserved function FN of AO as part of their prototype chain, as long as the preservation function a variable or variables will not be destroyed where AO not destroy the function FN of AO will never be destroyed function A stored in the variable can always access the variables and values in the function FN closure. A large number of such closures will lead to memory leaks or slow loading.

var Variable_1 = 1;
function FN() {
    var Variable_2 = 2;
    function A() {
        var Variable_3 = 3
        console.log(Variable_2);
    }
    return A;
}
var Function_A = FN();
FnVariable(); // 接受 函数A 的变量 Function_A 通过调用可以输出 FN 中的 Variable_2


海洋饼干
1.5k 声望191 粉丝