Let’s look at this code. What do you think the output of this code is?

showName()
console.log(myname)
var myname = 'Geek Time'
function showName() {
    console.log('Function showName executed');
}
Copy the code

Variable promotion (as)

Before introducing variable promotion, let’s take a look at what declarations and assignments are in JavaScript:

var myname = 'hello world'
Copy the code

You can view this as two lines of code:

var myname    // Declaration section
myname = 'Geek Time'  // Assignment section
Copy the code

As shown below:

Var var var var var var var var var var var var var var var var var var var var var var var var

function foo(){
  console.log('foo')}var bar = function(){
  console.log('bar')}Copy the code

The first function, foo, is a complete function declaration, that is, no assignment is involved; The second function declares the variable bar and assigns function(){console.log(‘bar’)} to bar. As shown below:

Ok, now that we understand declarations and assignments, we can talk about variable promotion.

The so-called variable promotion refers to the “behavior” in which the JavaScript engine promotes the declaration part of variables and functions to the beginning of the code during the execution of JavaScript code. When a variable is promoted, it is given a default value, which is known as undefined.

Let’s simulate the implementation:

/* * The variable promotion part */
// raise the variable myname to the beginning,
// Also assign myname to undefined
var myname = undefined
// promote the function showName to the beginning
function showName() {
    console.log('showName called ');
}

/* * Executable code part */
showName()
console.log(myname)
// Remove the var declaration part and keep the assignment statement
myname = 'Geek Time'
Copy the code

As you can see from the figure, there are two major changes to the original code:

  • The first is to promote the declared parts to the beginning of the code, such as variable myname and function showName, and set the default value of variables undefined.
  • The second is to remove the declared variables and functions, such as var myName = ‘geek time’ statement, remove the var declaration, and remove the showName function declaration altogether. Through these two steps, the effect of variable promotion can be achieved

The execution flow of JavaScript code

In the literal sense of the concept, “variable promotion” means that declarations of variables and functions are moved to the front of the code at the physical level, as we simulated. But that’s not accurate. The actual location of variable and function declarations in the code does not change and is put into memory by the JavaScript engine at compile time.

A piece of JavaScript code needs to be compiled by a JavaScript engine before it can be executed,compileOnly when you’re done will you enterperformPhase. You can refer to the following figure for the general process:

1. Compilation phase

So what is the relationship between compile phase and variable promotion?

To clarify this, let’s go back to the code above that simulates variable promotion, which can be divided into two parts for introduction purposes:

The first part: variable promotion part of the code.

Var myname = undefined function showName() {console.log(' showName '); }Copy the code

Part two: Executing part of the code.

ShowName () console.log(myname) myname = 'Geek time'Copy the code

Now we can refine the JavaScript execution process, as shown in the figure below:

As you can see from the figure above, when you enter a piece of code and compile it, you generate two parts: the Execution context and the executable code.

The execution context is the execution environment of JavaScript when executing a piece of code. For example, when calling a function, the execution context of the function will be entered, and the functions, such as this, variables, objects and functions, will be determined during the execution of the function.

The details of the execution context will be covered in the next article, but for now, there is a Viriable Environment in the execution context that holds the contents of the variable promotion, such as the myname variable and the showName function in the code above, Are stored in that object.

You can simply think of a variable environment object as the following structure:

VariableEnvironment:
     myname -> undefined, 
     showName ->function : {console.log(myname)
Copy the code

After understanding the structure of the variable environment object, we will analyze how to generate the variable environment object with the following code.

ShowName () console.log(myname) var myname = 'geeky time' function showName() {console.log(' function console.log '); }Copy the code

We can analyze the above code line by line:

  • Lines 1 and 2, because they are not declarative operations, the JavaScript engine does nothing;
  • In line 3, since this line is declared by var, the JavaScript engine will create a property named myName in the environment object and initialize it with undefined;
  • In line 4, the JavaScript engine finds a function defined by function, so it stores the function definition in the HEAP, creates a showName attribute in the environment object, and points the value of that attribute to the location of the function in the HEAP

This generates the variable environment object. The JavaScript engine then compiles the non-declared code into bytecode, analogous to the following mock code:

ShowName () console.log(myname) myname = 'Geek time'Copy the code

Now that you have the execution context and executable code, it’s time to execute.

2. Implementation phase

The JavaScript engine starts executing executable code, line by line, in sequence. Let’s break down the execution line by line:

  • When the showName function is executed, the JavaScript engine looks for the function in the variable environment object. Since there is a reference to the function in the variable environment object, the JavaScript engine executes the function and prints “function showName was executed.”
  • The JavaScript engine then prints the “myname” message and continues to look for the object in the variable environment. Since the variable environment has the myName variable and its value is undefined, it prints undefined.
  • Next line 3 assigns “geek time” to the myname variable and changes the value of the myname attribute in the variable environment to “geek time”.

This is the process of compiling and executing a piece of code.

What if the same variable or function appears in the code?

Take a look at the following code:

Function showName() {console.log(' geeky '); } showName(); Function showName() {console.log(' geek time '); } showName();Copy the code

Let’s analyze the complete execution process:

  • The first is the compile phase. When the first showName function is encountered, the body of the function is put into the variable environment. The second showName function will continue in the variable environment, but there is already a showName function in the variable environment, the second showName function will override the first showName function. This leaves only the second showName function in the variable environment.
  • Next comes the execution phase. The first showName function is executed, but since the showName function is found in the variable environment, where only the second showName function is stored, the second function is eventually called, printing “geek time.” The second execution of the showName function follows the same process, so the output is also “geek time.”

To sum up, if a piece of code defines two functions of the same name, then the last function is ultimately valid.

Conclusion:

  • Variable promotion is required during JavaScript code execution, and variable promotion is required because JavaScript code needs to be compiled before execution.
  • At compile time, variables and functions are stored in the variable environment, and the variable’s default value is set to undefined. During code execution, the JavaScript engine looks for custom variables and functions from the variable environment.
  • If there are two identical functions at compile time, the last one will end up in the variable environment, because the last one will override the previous one

Function promotions take precedence over variable promotions and are not overridden by variable declarations, but are overridden by variable assignments.

JavaScript execution mechanism: Compile first, execute later