JavaScript from definition to execution JS engine closure

Source: Internet
Author: User
Tags closure define function define local

JavaScript from definition to execution, JS engine has done a lot of initialization in the implementation layer, so before learning the JS engine working mechanism, we need to introduce several related concepts: execution environment stack, global object, execution Environment, variable object, activity object, scope and scope chain, etc. These concepts are the core components of the JS engine's work. The purpose of this article is to explain each concept in isolation, instead of analyzing it through a simple demo, explaining every detail of the JS engine from definition to execution, and the role that these concepts play in.

    1. var x = 1;   //defines a global variable  x 
    2. function a (y) { 
    3.     var x = 2;  //define a local variable  x 
    4.    function b (z) { 
    5.         Console.log (x+y+z);  
    6.    } 
    7.    return b; //returns a reference to function B  
    8. var c = a (1)  //execute A, return to b 
    9. C (1);  //execution function b 

This demo is a closure, the execution result is 4, below we will be divided into global initialization , execute function A, execute function B three stages to analyze the JS engine working mechanism:

First, global initialization

The JS engine needs to complete the following three initialization tasks as it enters an executable code:

First, create a global object that has only one copy globally, and its properties can be accessed anywhere, and its existence accompanies the entire life cycle of the application. When the global object is created, the common JS object, such as Math,string,date,document, is used as its property. Since this global object cannot be accessed directly by name, there is another property window, which points to itself so that the global object can be accessed through window. The general structure for simulating global objects with pseudo-code is as follows:

    1. Create a Global object
    2. var globalobject = {
    3. math:{},
    4. string:{},
    5. date:{},
    6. document:{}, //dom operation
    7. ...
    8. window: this//Let the window property point to itself
    9. }

The JS engine then needs to build an execution environment stack (execution context stack), while also creating a global execution Environment (execution context) EC and pressing the global execution environment EC into the execution environment stack. The role of the execution environment stack is to ensure that the program is executed in the correct order. In JavaScript, each function has its own execution environment, and when a function is executed, the execution environment of the function is pushed to the top of the execution environment stack and gets execution. When this function is completed, its execution environment is removed from the top of the stack and the execution is given back to the execution environment. We use pseudo-code to simulate the relationship between the execution environment stack and the EC:

    1. var ecstack = []; //define an execution environment stack, similar to an array
    2. var EC = {}; //Create an execution space,
    3. The ECMA-262 specification does not explicitly define the data structure of the EC, which you can understand as a space allocated in memory
    4. Ecstack.push (EC); //Enter function, press into execution environment
    5. Ecstack.pop (EC); after the function returns, delete the execution environment

Finally, the JS engine also creates a global variable object (Varibale object) VO associated with the EC, and the VO points to the global object, which includes not only the original properties of the global object, but also the globally defined variable x and function A, and at the same time, when the function A is defined, a An internal property scope is added and the scope is pointed to VO. Each function, when defined, creates a scope property associated with it, and the scope always points to the environment in which the function is defined. The ecstack structure at this time is as follows:

  1. Ecstack = [ //Execution Environment stack
  2. EC (G) = { //Global Execution Environment
  3. VO (G): { //define global variable object
  4. ... //contains the original properties of the global object
  5. x = 1; //define variable x
  6. A = function () {...}; //define function a
  7. A[[scope]] = this ; //define scope for a and assign a value of Vo itself
  8. }
  9. }
  10. ];

Second, executive function a

When execution enters a (1), the JS engine needs to complete the following tasks:

First, the JS engine creates the execution environment EC for function A, then the EC pushes the top of the execution environment stack and gets the execution right. There are two execution environments in the execution environment stack, namely the global execution environment and the function a execution environment, the execution environment of A is at the top of the stack, and the global execution environment is at the bottom of the stack. Then, create the scope chain of function A (scope Chain), in JavaScript, each execution environment has its own scope chain for identifier resolution, and when the execution environment is created, its scope chain is initialized to the objects contained in the scope of the currently running function.

The JS engine then creates an active object of the current function (Activation object) AO, where the active object plays the role of the variable object, except in the function (you can assume that the variable object is a general concept, and that the active object is a branch of it). The AO contains the formal parameters of the function, the arguments object, the This object, and the definition of local variables and intrinsic functions, and then the AO is pushed to the top of the scope chain. It is important to note that when defining function B, the JS engine also adds a scope property to B and points to the environment where function B is defined, and the environment in which function B is defined is the active object AO of a, and AO is at the front of the list, because the linked list has the characteristics Therefore, the scope of function B points to the entire scope chain of a. Let's look at the ecstack structure at this time:

  1. Ecstack = [ //Execution Environment stack
  2. EC (A) = { //a's execution Environment
  3. [Scope]:vo (G), //vo is a global variable object
  4. AO (A): { //Create the active object of function A
  5. Y:1,
  6. X:2, //define local variable x
  7. B:function () {...}, //define function B
  8. B[[scope]] = this ; //this refers to the AO itself, while AO is at the top of the Scopechain, so B[[scope]] points to the entire scope chain
  9. Arguments:[],//The arguments that we access in the function is the arguments in the AO
  10. The This in the This:window//function points to the caller window object
  11. },
  12. Scopechain:<ao (a),a[[scope]]> //list is initialized to A[[scope]] and then joins the AO to the top of the scope chain, at which point A's scope chain: AO (a)->vo (G)
  13. },
  14. EC (G) = { //Global Execution Environment
  15. VO (G): { //Create global variable object
  16. ... //contains the original properties of the global object
  17. x = 1; //define variable x
  18. A = function () {...}; //define function a
  19. A[[scope]] = this ; //Definition of a scope,a[[scope]] = = VO (G)
  20. }
  21. }
  22. ];

Third, executive function b

After function A is executed, a reference to B is returned, assigned to the variable C, execution C (1) is equivalent to B (1), and the JS engine needs to do the following:

First, as in the above, create the execution Environment EC for function B, then the EC pushes the top of the execution environment stack and gets the execution right. There are two execution environments in the execution environment stack, namely the execution environment of the global execution environment and function B, the execution environment of B is at the top of the stack, and the global execution environment is at the bottom of the stack. (Note: When function A returns, the execution environment of a is removed from the stack, leaving only the global execution environment) and then the scope chain of function B is created and initialized to the object contained in the scope of function B, which contains the scope chain of a. Finally, the active object of function B is created AO, and the parameter Z of B, the arguments object, and the This object are the properties of the AO. At this point the Ecstack will become this:

  1. Ecstack = [ //Execution Environment stack
  2. EC (b) = { //Create execution Environment for B and at the top of the scope chain
  3. [Scope]:ao (a), //scope chain to function A, AO (a)->vo (G)
  4. var AO (b) = { //Create Activity object for function B
  5. Z:1,
  6. Arguments:[],
  7. This:window
  8. }
  9. Scopechain:<ao (b),b[[scope]]> //list is initialized to B[[scope]], then AO (b) is added to the list header, at this time the scope chain of B: AO (b)->ao (A)-vo (G)
  10. },
  11. EC (A), //a's execution environment has been removed from the top of the stack,
  12. EC (G) = { //Global Execution Environment
  13. vo:{ //Defining global variable Objects
  14. ... //contains the original properties of the global object
  15. x = 1; //define variable x
  16. A = function () {...}; //define function a
  17. A[[scope]] = this ; //Definition of a scope,a[[scope]] = = VO (G)
  18. }
  19. }
  20. ];

When function B executes "x+y+z", the X, Y, and z three identifiers need to be parsed one by one, and the parsing process follows the variable lookup rule: finds the attribute in its active object first, stops the lookup and returns if it exists, and, if it does not, continues to find it from the top of its scope chain until it is found Returns "Undefined" if the variable is not found on the entire scope chain. From the above analysis, we can see that the scope chain of function B is this:

AO (B)->ao (A)->vo (G)

Therefore, the variable x is found in AO (a), not the X in Vo (G), the variable y is also found in AO (a), and the variable z is found in its own AO (B). So the result of execution: 2+1+1=4.

A simple summary of the language

After understanding the working mechanism of JS engine, we can not only stay at the level of understanding the concept, but as a basic tool to optimize and improve our actual work of the code, improve the efficiency of implementation, the actual value is our real purpose. In terms of the variable lookup mechanism, if your code is deeply nested, each time a global variable is referenced, the JS engine looks for the entire scope chain, such as the bottom window and document object at the scope chain, so we can do a lot of performance optimization around this problem. Of course, there are other aspects of the optimization, not to repeat here, this article only as a point!

"Editor's recommendation"

    1. Summary of JavaScript floating-point number and operation precision Adjustment
    2. A JavaScript engine guide for small white
    3. The most detailed JavaScript developer survey Report
    4. Dry share: Let you learn JavaScript closures in minutes
    5. JavaScript's this pointer in-depth explanation
    6. JavaScript typeof and instanceof in-depth explanation
    7. Christmas, dress up your JavaScript code as a Christmas tree.

Reproduced in 51CTO.

JavaScript from definition to execution JS engine closure

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.