The “precompile phase” that somehow appears

As we all know, JS is an interpreted language, not a compiled language (the following is a very brief description of the two differences).

A computer cannot understand or execute a high-level language. It can only understand machine language. Therefore, any program in a high-level language must be converted into computer language (machine code) before it can run.1.Compilation: Before a compiled language program can be executed, a special compilation process is required to compile the source code into machine language so that the compiled results can be used directly when it is run again2.Interpretation: Interpreted languages do not require pre-compilation; they interpret the source code directly into machine code and begin execution immediately.Copy the code

JavaScript, which pretends to be an interpreted language, does not have a “precompile” stage, so it is more appropriate to call it “precompile”. It doesn’t really matter what it is called, but why do many students think that JS has a “precompiled” stage? What kind of behavior is it that causes many students to think that JS has a “precompiled” stage? Here we ask the question

Q: JS is an interpreted language, so precompilation doesn’t exist, so what kind of behavior makes people think it does? A: Because of the lexical context and variable promotion

Lexical context and variable promotion

Before introducing the lexical environment, let’s take a look at the JS compilation and execution process in V8, which can be roughly viewed as three stages.

1. Word segmentation/lexical analysis stage: word segmentation refers to the separation of the code, such as var a = 2, will be split into symbols such as var,a,=,2; Lexical analysis refers to: analysis of parameters, analysis of variables declaration, analysis of function declaration (here will be this stage to understand a general, interested please refer to the relevant books, here does not elaborate too much) 2. Parsing/parsing: At the end of word segmentation, code parsing is performed, and the engine translates the token parsing into an AST(abstract syntax tree). At this stage, if syntax errors are found, an error is reported and no further execution is performed. 3. Code generation phase: The engine generates machine code that the CPU can execute. (Reading this article requires only a brief understanding of the lexical analysis stage.)

At the Lexical analysis stage, an internal (hidden) correlation object (with various translations, I generally call it Lexical Environment object) is created for the Lexical Environment.

A lexical Environment object consists of two parts: 1. An Environment Record — an object that stores all local variables as its properties (including some other information). 2. References to external lexical environments (OUTER) — associated with external code.

A variable is just a property of the object recorded by the environment, and getting or modifying a variable is equivalent to getting or modifying a property of the lexical environment object.

The lexical environment corresponds to the structure of our own code, that is, the lexical environment is the way our own code is written. The lexical environment is determined when the code is defined, regardless of where the code is called. So JavaScript uses lexical scope (static scope).

Declare a variable in a global lexical environment object:

execution start     //a:<uninitialized>
let a ;             //a:undefined
a=1;                //a:1
a=2                 //a:2
Copy the code

The above example shows how global lexical environment objects change when variables are declared (with slightly different function declarations, as described below) :

1. When the script starts running, the lexical environment is prepopulated with all declared variables. Initially, they are in the “Uninitialized” state. This is a special internal state, which means that the engine knows about the variable, but cannot refer to it until it is declared with let. It’s almost as if the variable doesn’t exist. 2. Then the let a definition appears. It has not been assigned, so its value is undefined. From this point on, we can use variables. A is assigned a value. 4. A is modified

Now, let’s say that out loud: ‘Manipulation variables are actually properties of manipulation lexical environment objects. ‘

There are a few differences between function declarations and variable declarations. Without further ado, above:

execution start      //a:<uninitialized>,b:function
let a='a';
function b(){... }Copy the code

We can see that the difference between a variable declaration and a function declaration is that the variable is “uninitialized” when it is filled and cannot be referred to yet, but the function initialization is completed immediately when the function is filled and the function declaration becomes a ready-to-use function

An apology

I deleted the back to write too messy…..

The two small pictures above should give students a glimpse of the lexical environment object. Of course, WHEN I used the variable declaration example, I only used the let declaration example, but there are some differences between using the var declaration and the let declaration. I will not write this article, after all, just to quickly get a superficial understanding of the lexical environment object, if I am still interested in the let declaration and var declaration in the lexical environment object are different. This is the first article I have written. I don’t have much experience in writing, but I feel my writing style is very poor, my thinking logic is chaotic, and the overall layout is not clear. It is really difficult to write this article.

If the students can see here, don’t swipe away yet, please give a thumbs-up, give a little encouragement