In-depth understanding of the JavaScript execution context (execution context)

Source: Internet
Author: User
Tags variable scope

This article transferred from: http://blogread.cn/it/article/6178

In this article, we will take a closer look at the most basic and important concepts in execution context-JavaScript. After reading this article, you will understand what the JavaScript engine does inside the code before executing it, why some functions and variables can be used before they are declared, and how their final values are defined.

What is the execution context

The code in JavaScript is run in the following three categories:

    • Global level code-this is the default code runtime environment, and once the code is loaded, the engine first enters the environment.

    • Code at the function level-when executing a function, run the code in the body of the function.

    • Eval code-code that runs within the Eval function.

In order to make this article easy to understand, a lot of resources can be found on the web, so we can think of the execution context as the running environment or scope of the current code. Let's look at an example that includes the global and function-level execution contexts:

, a total of 4 execution contexts are used. The purple represents the global context; Green represents the context within the person function; blue and orange represent the context of the other two functions within the person function. Note that, in any case, there is only one global context that can be accessed by any other context. That is, we can access the SayHello variable in the global context in the context of the person, but it can also be accessed in the function FirstName or LastName.

As for the number of function contexts there is no limit, every call to execute a function, the engine will automatically create a new function context, in other words, a new local scope, you can declare a private variable in the local scope, in the external context is not directly accessible to the element within the local scope. In the above example, the internal function can access the declared variables in the external context, and vice versa. So what is the reason for this? How is the engine handled inside?

Execution context Stack

In the browser, the JavaScript engine works in a single-threaded way. That is, only one event at a time is activated and other events are placed in the queue waiting to be processed. The following example diagram depicts such a stack:

We already know that when JavaScript code files are loaded by the browser, the default first entry is a global execution context. When a function is called in the global context, the program flow enters the called function, and the engine creates a new execution context for the function, and presses it into the top of the execution context stack. The browser always executes the current context at the top of the stack, and once executed, the context is ejected from the top of the stack and then into the context under which the code executes. The context in the stack is then executed sequentially and the stack pops up until it returns to the global context. Take a look at the following example:

1
2
3
4
5
6
7
8
function foo (I{
   if  (I === 3{
       return;
   
   else {
       foo++i    
} (0 )

After the above Foo is declared, it is forced to run directly through the () operator. The function code is called itself 3 times, each time the local variable i is increased by 1. Each time the Foo function is called by itself, a new execution context is created. Whenever a context executes, the upper context is ejected from the stack, returning to the previous context until it returns to the global context again. The process is abstract as follows:

Thus, the abstract concept of the execution context can be summed up in the following points:

    • Single Thread

    • Synchronous execution

    • The only global context

    • There is no limit to the number of execution contexts for a function

    • Each time a function is called, a new execution context is created for it, even if the function is called itself.

Execution context Creation process

We now know that whenever a function is called, a new execution context is created. However, within the JavaScript engine, this context is created in two stages:

    1. Build phase (occurs when a function is called, but before the specific code in the body of the function is executed)

      • Create variables, functions, arguments objects, parameters

      • Creating a Scope chain

      • Determine the value of this

    2. Code Execution phase:

      • Variable assignment, function reference, execution of other code

In fact, the execution context can be seen as an object with the following 3 properties:

1
2
3
4
5
Executioncontextobj = {
Variableobject: {/ * arguments object in the function, arguments, internal variables, and function declarations */ },
Scopechain: {/ * Variableobject and all variableobject in the parent execution context */ },
this: {}
}
Detailed analysis of the setup phase and code execution phase

To be exact, the execution context object (Executioncontextobj above) is created when the function is called, but before the function body is actually executed. When a function is called, it is the first phase in the two phases described above-the build phase. At this point, the engine examines the arguments in the function, the declared variables, and the intrinsic functions, and then builds the execution context object (Executioncontextobj) based on that information. At this stage, the Variableobject object, the scope chain, and the object to which this is directed will be determined.

The specific process for the first phase above is as follows:

    1. Find the code for the calling function in the current context

    2. Before executing the code in the called function body, start creating the execution context

    3. Enter the first stage-the build phase:

      • To create a Variableobject object:

        1. Establish a arguments object, examine the parameters in the current context, establish the properties under the object, and attribute values

        2. Check the function declaration in the current context:

          • Each time a function declaration is found, a property is established with the function name under Variableobject, and the property value is a reference to the address of the function in memory.

          • If the above function name already exists under Variableobject, then the corresponding property value will be overwritten by the new reference.

        3. Check the variable declaration in the current context:

          • Every declaration of a variable is found, under Variableobject, a property is created with the variable name, and the property value is undefined.

          • If the variable name already exists in the Variableobject property, skip directly (prevent the value of the property pointing to the function from being overwritten by the variable property to undefined), the original property value will not be modified.

      • Initialize the scope chain

      • Determines the pointing object of this in context

    4. Code Execution phase:

      • Executes the code in the function body, runs the code one line at a line, assigns a value to the variable attribute in the Variableobject.

Let's look at a specific code example:

1
2
3
4
5
6
7
8
9
10
11
function foo(i) {
var a = ' Hello ';
var b = function Privateb() {

};
function C() {

}
}

Foo(+);

When calling Foo (22), the setup phase is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Fooexecutioncontext={
Variableobject:{
Arguments:{
0:22,
Length: 1
       }        i: 22        c: pointer to function c (        a: undefined        b: undefined
   }    scopechain: { ... }    this: { ... 
} /span>

Thus, in the establishment phase, in addition to arguments, function declarations, and parameters are given specific property values, the other variable properties default is undefined. Once the build phase is completed, the engine goes into the code execution phase, after which the execution context object is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Fooexecutioncontext={
Variableobject:{
Arguments:{
0:22,
Length:1
},
I: 22,
       C : pointer to function c (
       a:  ' hello '        b: pointer to function privateb ()
   }     Scopechain: { ... }
   this: { ... 
} /span>

We see that the variable properties are given a specific value only during the code execution phase.

Reasons for local variable scope promotion

It has been seen on the Internet that variables and functions declared in a function are scoped to the top of the function, in other words, the variables and functions declared in the function can be accessed as soon as they enter the body. This is right, but do you know the reason? I believe you should understand that through the above explanation. But here's a second analysis. Look at the following section of code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(function(){

Console.Log(typeof Foo);function pointer
Console.Log(typeof Bar);Undefined

var foo =  ' hello '        bar = function ({
           return < Span class= "St0", "World"        }
   function foo ()   {
       return  ' hello '    }

} (

The code above defines an anonymous function and enforces an understanding of execution through the () operator. Then we know that this time there will be an execution context is created, we see in the example immediately can access Foo and bar variable, and through typeof output Foo as a function reference, bar is undefined.

      • Why can we have access to Foo before declaring the foo variable?

        Because in the context of the establishment phase, first processing arguments, parameters, then the declaration of the function, and finally the declaration of the variable. Then, after discovering the declaration of the Foo function, a foo attribute is established under Variableobject, whose value is a reference to the function. The declaration of Var foo was found when processing the variable declaration, but the Variableobject already has the Foo attribute, so skip directly. When entering the code execution phase, it is possible to access the Foo property because it already exists and is a function reference.

      • Why is bar undefined?

        Because bar is the declaration of a variable, the default value given is undefined at the time of the establishment phase. Since it is given a specific value only during the code execution phase, the output value is undefined when the typeof (bar) is called.

In-depth understanding of the JavaScript execution context (execution context)

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.