The JavaScript execution sequence is described in detail

  • 2020-03-30 00:44:46
  • OfStack

After exploring how JavaScript works from the parsing mechanism of the JavaScript engine, let's take a more visual example to illustrate the order in which JavaScript code is executed on a page. If the working mechanism of JavaScript engine is more profound because it belongs to the underlying behavior, then the execution order of JavaScript code is relatively vivid, because we can intuitively feel the execution order. Of course, the execution order of JavaScript code is relatively complex, so it is necessary to analyze it before diving into the JavaScript language.
1.1   Execute the JavaScript code in HTML document flow order
First, the reader should be aware that HTML documents are parsed in the browser in such a way that the browser parses the page structure and information from top to bottom in a document stream. JavaScript code, as embedded scripts, should also be considered part of the HTML document, so the order in which JavaScript code is executed at load is also based on the script tag. Script> To determine the order of occurrence. For example, if you look at the following document page, you can see that the code is parsed from top to bottom.


<script>
alert(" At the top of the script ");
</script>
<html><head>
<script>
alert(" The head script ");
</script>
<title></title>
</head>
<body>
<script>
alert(" The page script ");
</script>
</body></html>
<script>
alert(" At the bottom of the script ");
</script>

If by script label < Script> The SRC attribute imports the external JavaScript file script, and it too executes in the order in which its statements appear, and the execution is part of the document load. Execution is not delayed because it is an external JavaScript file. For example, move the scripts from the header and body areas in the above document to an external JavaScript file and import them through the SRC attribute. Continue to preview the page documents and you will see the same order of execution.


<script>
alert(" At the top of the script ");
</script>
<html>
<head>
<script src="//www.jb51.net/head.js"></script>
<title></title>
</head>
<body>
<script src="//www.jb51.net/body.js"></script>
</body>
</html>
<script>
alert(" At the bottom of the script ");
</script>

1.2   Precompilation versus execution order

In Javascript, function is the first type of Javascript. When we write down a function, we are simply creating a function-type entity.
Just as we could write it in this form:


functionHello() 
{
alert("Hello"); 
}
Hello(); 
varHello = function() 
{
alert("Hello");
} 
Hello(); 

It's the same thing. But when we modify the functions in it, we find some strange problems.

<scripttype="text/javascript">        
functionHello() {         
alert("Hello");   
}        
Hello();      
functionHello() {   
alert("Hello World");    
}        
Hello();    
</script>

We see the result: Hello World output twice in a row.
Instead of Hello and Hello World as we imagine them.
This is because Javascript is not fully interpreted and executed in order. Instead, Javascript is precompiled before interpretation. In the process of precompilation, defined functions are prioritized and all var variables are created with the default value of undefined to improve the execution efficiency of the program.
In other words, the above code is actually precompiled by the JS engine to look like this:

<scripttype="text/javascript">        
varHello = function() {           
alert("Hello");        
}       
Hello = function() { 
           alert("Hello World");  
      }      
Hello();     
Hello();  
</script> 

As we can see clearly from the above code, functions are also data and variables, and we can also assign (re-assign) functions.
Of course, in order to prevent such a situation, we can also:

<scripttype="text/javascript">      
functionHello() {        
alert("Hello");       
}        
Hello();  
</script>   
<scripttype="text/javascript">   
functionHello() {          
alert("Hello World");     
}       
Hello();  
</script>

In this way, the program is divided into two segments, and the JS engine will not put them together.      

When the JavaScript engine parses the script, it handles all declared variables and functions at precompile time.

Do the following:

1. Before the execution will be carried out in a similar "precompiled" operation: first of all, will create a current execution environment of active objects, and those who use the var statement variable is set to the activities of the object's properties, but the variable assignment is undefined, and defines the function to the attributes of the object function is also added as activity, and it is function definition of their values.

2. During the explain execution phase, when variables need to be resolved, it will first look for them from the active object of the current execution environment. If it fails to find them and the owner of the execution environment has the prototype property, it will look for them from the prototype chain; otherwise, it will look for them according to the scope chain. Var a =... Such a statement will assign a value to the corresponding variable (note: the value of the variable is assigned during the explain execution phase, and if the variable is used before then, the value will be undefined). Therefore, it will appear that the JavaScript interpreter will not report an error when it executes the following script:


alert(a);                            //The return value undefined
var a =1;
alert(a);                            //The return value of 1

Because the variable declaration is processed at precompile time, it is visible to all code during execution. However, you will also see that when you execute the above code, the value is undefined, not 1. This is because the variable initialization occurs during execution, not during precompilation. During execution, the JavaScript interpreter parses in code order and USES the default value undefined if the variable is not assigned in the previous line of code. Since the variable a is assigned in the second line, in the third line the value of variable a is prompted to be 1, not undefined.

Likewise, the following example is legal to call a function before it is declared and can be parsed correctly, so the return value is 1.


f();                                 //Call the function and return the value 1
function f(){
    alert(1);
}

However, if the function is defined as follows, the JavaScript interpreter prompts for a syntax error.


f();                                 //Call the function to return a syntax error
var f = function(){
    alert(1);
}

This is because the function defined in the above example is only assigned to variable f as a value, so the JavaScript interpreter can only handle declaring variable f at precompile time, while the value of variable f can only be assigned sequentially at execution time, which naturally results in syntax errors and indicates that the object f cannot be found.

See some more examples:


<script type="text/javascript">

alert(func); //function func(){alert("hello!")}
var func = "this is a variable"
function func(){
alert("hello!")
}

alert(func);  //this is a variable
</script>


<script type="text/javascript"> 
var name = "feng"; function func()
{ 
 
alert(name);  //undefined var name = "JSF"; 
alert(name);  //JSF 
}
func(); 
alert(name); 
//feng
</script>

While variable and function declarations can be made anywhere in the document, it is a good practice to declare global variables and functions and initialize variables before any JavaScript code. Inside the function, variables are declared and then referenced.

1.3   Execute JavaScript code in blocks

A block of code USES < Script> Tag delimited code segment. For example, the following two < Script> The tag represents two blocks of JavaScript code.


<script>
//JavaScript block 1
var a =1;
</script>
<script>
//JavaScript block 2
function f(){
    alert(1);
}
</script>

When the JavaScript interpreter executes a script, it executes it in blocks. In layman's terms, when a browser is parsing an HTML document stream, it encounters an < Script> Tag, the JavaScript interpreter waits until the block is loaded, precompiles the block, and then executes it. After execution, the browser continues to parse the following HTML document stream, and the JavaScript interpreter is ready to process the next block of code.

Because JavaScript is executed in blocks, a syntax error is prompted if a variable or function declared in a later block is called in a JavaScript block. For example, when the JavaScript interpreter executes the following code, it prompts for a syntax error, showing that variable a is undefined and object f cannot be found.


<script>
//JavaScript block 1
alert(a);
f();
</script>
<script>
//JavaScript block 2
var a =1;
function f(){
    alert(1);
}
</script>

Although JavaScript is executed in blocks, different blocks are in the same global scope, meaning that variables and functions between blocks can be Shared.

1.4   Change the JavaScript execution order with the event mechanism

Because JavaScript processes code in blocks and follows the parsing order of the HTML document stream, you can see this syntax error in the above example. However, when the document stream is loaded, there is no such error if it is accessed again. For example, if you place the code that accesses the variables and functions in block 2 in the page initialization event function, you won't get syntax errors.


<script>
//JavaScript block 1
window.onload = function(){        //The page initializes the event handler
    alert(a);
    f();
}
</script>
<script>
//JavaScript block 2
var a =1;
function f(){
    alert(1);
}
</script>

To be safe, we generally allow JavaScript code to execute after the page has been initialized to avoid the impact of network speed on JavaScript execution, as well as the limitations of HTML document flow on JavaScript execution.

Pay attention to

If there are multiple Windows.onload event handlers on a page, only the last one is valid. To solve this problem, you can put all scripts or call functions in the same onload event handler, for example:


window.onload = function(){
    f1();
    f2();
    f3();
}

And in this way you can change the order in which the functions are executed by simply adjusting the order in which the functions are called in the onload event handler.

In addition to page initialization events, we can also change the execution order of JavaScript code through various interactive events, such as mouse events, keyboard events, and clock triggers. Please refer to chapter 14 for details.

1.5   JavaScript outputs the order in which scripts are executed

In JavaScript development, it is common to output JavaScript scripts using the write() method of the document object. So how are these dynamic output scripts executed? Such as:


document.write('<script type="text/javascript">');
document.write('f();');
document.write('function f(){');
document.write('alert(1);');
document.write('}');
document.write('</script>');

If we run the above code, we will find that: document.write() method first writes the output script string to the document location where the script is located. After the browser parses the contents of the document.write() document, it continues to parse the contents of the output document.write(), and then parses the subsequent HTML documents in order. That is, the code string that the JavaScript script outputs is executed immediately after the output.

Note that the JavaScript script string that is output using the document.write() method must be placed in the < Script> Tag, otherwise the JavaScript interpreter cannot recognize the legitimate JavaScript code and displays it as a normal string in the page document. For example, the following code displays the JavaScript code instead of executing it.


document.write('f();');
document.write('function f(){');
document.write('alert(1);');
document.write(');');

However, there is a risk of outputting the script and executing it through the document.write() method, because different JavaScript engines execute it in different orders, and different browsers have bugs when parsing it.

& Oslash; Problem 1: you cannot find the variables or functions declared in the external JavaScript file imported through the document.write() method. For example, take a look at the following sample code.


document.write('<script type="text/javascript" src="//www.jb51.net/test.js">
</script>');
document.write('<script type="text/javascript">');
document.write('alert(n);');  //IE prompts that the variable n cannot be found
document.write('</script>');
alert(n+1);                          //All browsers will tell you that the variable n cannot be found

The code for the external JavaScript file (test.js) is as follows:


var n = 1;

When tested in different browsers, you will find a syntax error and the variable n cannot be found. That is, if you access the variables contained in the imported external JavaScript file in the script output using the document.write() method in the JavaScript block, the syntax error will be shown. At the same time, if you are in Internet explorer, not only in the script, but also in the output script will be prompted to find the output of the imported external JavaScript file variables (the statement is a bit long and convoluted, do not understand the reader can try to run the above code to understand).

& Oslash; The second problem is that different JavaScript engines have slightly different orders of execution for external import scripts for output. For example, take a look at the following sample code.


<script type="text/javascript">
document.write('<script type="text/javascript" src="http://shaozhuqing.com/test1.js">
</script>');
document.write('<script type="text/javascript">');
document.write('alert(2);')
document.write('alert(n+2);');
document.write('</script>');
</script>
<script type="text/javascript">
alert(n+3);
</script>

The code for the external JavaScript file (test1.js) is shown below.

var n = 1;
alert(n);

The order of execution in IE is shown in figures 1-6.

< img border = 0 SRC = "/ / files.jb51.net/file_images/article/201312/2013124170730730.png" >

Figure 1-6   IE 7 browser execution order and prompt syntax errors

The order of execution in a DOM compliant browser is different from that in Internet explorer, with no syntax errors, as shown in figure 1-7 in Firefox 3.0.

< img border = 0 SRC = "/ / files.jb51.net/file_images/article/201312/2013124170907704.png" >

Figure 1-7   Execution order and syntax errors in the Firefox 3 browser

Addresses different execution orders in different browsers and possible bugs. We can avoid this problem by placing all external files imported using the output script in separate code blocks according to the sequence of JavaScript code blocks described above. For example, for the example above, you could design it like this:


<script type="text/javascript">
document.write('<script type="text/javascript" src="//www.jb51.net/test1.js"></script>');
</script>
<script type="text/javascript">
document.write('<script type="text/javascript">');
document.write('alert(2);') ; //2
document.write('alert(n+2);'); //Tip 3
document.write('</script>');
alert(n+3); //Tip 4
</script>
<script type="text/javascript">
alert(n+4); //Tip 5
</script>

This allows the above code to be executed sequentially in different browsers, and the output order is 1, 2, 3, 4, and 5. The cause of the problem is the contradiction between the output imported script and the current block of JavaScript code. If the output was separate, there would be no conflict.


Related articles: