This is my first article on getting started

preface

A thought triggered by an interview question

As a common interview test, JavaScript precompilation is believed to be familiar. As a front-end engineer who has worked for many years, I thought I knew this part by heart. However, in the process of scanning the interview questions, he accidentally overturned the car. What kind of problem is it? Let’s take a look.

The problem parts

    function m(){
        console.log(a1);
        console.log(a2);
        console.log(b1);
        console.log(b2);
        if(false) {function b1(){};
            var a1 = 100;
        }
        if(true) {function b2(){};
            var a2 = 10;
        }
    }
    m();
Copy the code

If your answer is to print 4 undefined, congratulations, you have a pretty solid foundation in precompilation. If both A1 and A2 are wrong, it is recommended to read the following to reinforce the following foundations. If you’re just curious why b1 and b2 are undefined; Skip to the “Look and Think” section at the end of this article to read!

One, the embodiment of JavaScript precompilation

JavaScript precompilation refers to the behavior that some variables will be resolved in advance during the running of JS. Without this behavior, JS, like many other languages, will not be able to parse “use first, define later” variables.

    a = 2;  // If not precompiled, this code will report an error!
    var a;  // In js this code is actually compiled first, so JS does not report errors for this code
Copy the code

However, JS does not precompile for all variables, such as ES6 lets,const declarations. In fact, the JS compiler only preprocesses ————var and function keywords

Var and function

So what does JavaScript do when it preparses var and function? First JavaScript creates a global object, GO, which can be thought of as a window. This global object collects only two things:

  • One is var variables and functions defined globally, and the other is variables that are not declared in function callsCopy the code
    // var a = undfined
    function b(){
        a = 10; // Use undefined variables. A variable with the same name will be defined in GO during execution
    }
    b();
Copy the code

It is worth noting that GO assigns a to undefined, which is not an individual case. JS will GO through the code from top to bottom to find all variables declared by var and record them in GO. It also records all functions that use the function declaration in GO and assigns the corresponding function body to the function declaration

// console.log(a) //undefined
var a = 1;
function b(){} // In GO will be initialized to {a:undefined b:function b(){}}
Copy the code

After that, the code will actually be executed. For example, in the code above, the value of a is first assigned as undefined during the precompilation process, and then the code is executed. When var a = 1 is executed, the value of A will actually change to 1.

Function definitions are precompiled at compile time, so compilation is skipped until the function is executed. During compilation, each function produces an active object AO similar to GO. AO is similar to GO, but its scope is limited to a function and is generated as the function is generated. If a variable exists in the AO of the function and also exists in GO, then the variable in the AO will be searched first. If the variable does not exist, the higher level will be searched until GO is found.

var a = 10; function b(){ var a = 100; console.log(a); // 100, this can't be 10}Copy the code

We just discussed the situation where there are no variables in the AO. What happens if there are many variables with the same name in the AO?

function a(b){
    console.log(b);
    var b  = 10;
    function b(){};
    console.log(b);
}
a(1);
Copy the code

In this case, b is defined only once in function A’s AO, and the value of b defined later overrides the previously defined value. So in what order is this covered?

Remember the order function > parameter >var variable!!

In other words, under the same AO, I will first find var b, and then assign it as undeii. Then I will find parameter B, because the passed parameter is 1, so B =1. Finally, I will find the function declaration B, so THAT B in the AO will be assigned a function. So, when precompiled and executing code, the first console.log(b) prints function b(){}, followed by var b = 10; Function b is already precompiled and will not be executed again, so the second console.log(b) will print 10.

Observe and think

Go back to the question at the beginning of the passage. If (var, function) is not included in precompile (var, function). In precompilation, the JS engine does not consider whether the if will actually be executed. It only records all var and function faithfully. However, according to the previous theory, when recording function, JS will record the function name and assign it the function body, so why undefined?

I don’t have any data on this. We can only analyze it based on what we have. If (true) and if(false) return the same result, indicating that the JS engine did not parse the contents of the if. It is speculated that the JS engine will return the function as undefined when it meets the condition that needs to be judged.

function m() {
    console.log(i);
    var i = 2;
    while(i<0) {// this is also a conditional statement
        function i() {          
        }
    }
}
m(); I am therefore therefore worth 25 yuan
Copy the code

Therefore, we can simply assume that when function is defined in a conditional statement, JS preparsing will assign it undefined instead of function