Simple comprehension of scopes and scope chains in JavaScript (variable elevation)

Source: Internet
Author: User

By reading the "JS Advanced Program Design" This book, the scope of JS and the scope of the chain knowledge has a preliminary understanding and understanding, ready to take notes for your reference, notes in more words, but personally think the narrative is quite detailed, so I hope the reader patience to see. Moreover, I understand the comparative basis, the lack of local people want to exchange together and learn together.

1. Execution environment (execution context)

The execution environment defines the other data that variables and functions have access to, and determines their behavior. Each execution environment has a corresponding variable object (variable object) that holds all the variables and functions defined in the environment. We cannot access the variable object through code, but the parser uses it in the background when it processes the data.

The execution environment has a global execution environment (also known as a Global environment) and a function execution environment. The execution environment exists when the name is running and executing code, so we create a global execution environment when we run the browser, and when the function is called, the function execution environment is created.

1.1 Global Execution Environment

The global execution environment is the outermost execution environment, and in a Web browser we can think of him as a Window object, so all global variables and functions are created as properties and methods of the Window object. When the code loads into the browser, the global environment is created, the global environment is destroyed when the Web page is closed or when browsing is closed.

1.2 Function Execution Environment

Each function has its own execution environment, and when the execution flow enters a function, the environment of the function is pushed into an environment stack, and when the function is finished, the stack ejects its environment and returns control to the previous execution environment.

2 scope, scope chain 2.1 global scope (Globe scope) and local scope (local scope)

  Global Scopes can be accessed anywhere in the code, such as:

1  var name1= "haha"; 2 function Changname () {3     var name2= "Xixi"; 4     Console.log (name1);//Haha5     Console.log (name2);//Xixi6} 7 Changname (); 8 Console.log (name1);//haha9 Console.log (name2);//uncaught Referenceerror : Name2 is not defined

Where NAME1 has a global scope, so the 4th and 8th lines will output haha on the console. NAME2 is defined inside the Changname () function and has a local scope, so on line 9th, the parser cannot find the variable name2, throwing an error.
In addition, if you omit the var operator when declaring a variable in a function, the declared variable is a global variable and has a global scope, but it is not recommended because it is difficult to maintain a defined global variable in a local scope.

Furthermore, the built-in properties of the Window object have global scope.

Local scopes are generally accessible only within a fixed code fragment, such as name2 in the code above, which can be accessed only within the function.

2.2 Scope chain (scope chain)

The access rights of variables in global scope and local scope are actually determined by the scope chain.

Each time you enter a new execution environment, you create a scope chain that is used to search for variables and functions. A scope chain is a collection of objects in the scope in which the function is created. A scope chain guarantees an orderly access to all variables and functions that the execution environment has access to.

The most front-end of a scope chain is always the variable object of the environment in which the code is currently executing (if the environment is a function, its active object is the variable object), the next variable object is from the containing environment (which contains the current row environment), and the next variable object comes from the containing environment that contains the environment, Variable object until the global execution environment. The variable object of the global execution environment is always the last object in the scope chain.

Identifier parsing is the process of searching for identifiers up to the scope level. The search process always moves backwards from the front end of the scope until an identifier is found (which causes an error to occur).

For example:

1 var name1 = "haha"; 2 function ChangeName () {3     var name2= "Xixi"; 4     function Swapname () {5         console.log (name1);//haha 6         Console.log (name2);//xixi 7         var tempname=name2; 8         name2=name1; 9         name1=tempname;10         Console.log ( NAME1);//xixi
Console.log (name2);//haha12 Console.log (tempname);//xixi
}14 swapname (); Console.log (name1);//haha16 Console.log (name2);//xixi17 // Console.log (tempname); Throw error: Uncaught referenceerror:tempname is not defined18}19 changname (); Console.log (name1); 21 Console.log (name2); Throw error: Uncaught referenceerror:name2 is not defined22//console.log (tempname); Throw error: Uncaught referenceerror:tempname is Not defined

The results of the operation are as follows:

In the code above, there are three execution environments: the global environment, the local environment of the ChangeName (), and the local environment of the Swapname (). So

1. The scope chain of the function Swapname () contains three objects: its own variable object----->changename () The variable object of the local Environment-----> Global environment variable object.

2. Function ChangeName () has a scope of two objects: its own variable object-----> Global environment Variable object.

In terms of the variables and functions appearing in the above program (regardless of the invisible variable):

1.swapName () The variable tempname is stored in the variable object of the local environment;

2.changeName () Variables name2 and function swapname () are stored in the variable object of the local environment;

3. The variable object in the global environment holds the variable name1, function changename ();

In the execution Environment of Swapname (), when the 5th sentence is executed, the parser looks backwards at the scope chain level of the function swapname () to find the variable name1, until the variable name1 is found in the global environment. and output on the console. Similarly, when executing the 6th sentence of code, the parser follows the scope chain of the function swapname () One level backward and discovers the variable name2 in the Variable object of function ChangeName (). Exchange name1 and name2 through code and output on the console, As a result, we find that the values of these two variables are indeed exchanged. So we can conclude that the local environment of the function can access variables in the scope of the function, and can also access and manipulate the parent environment (including the environment) and even the variables in the global environment.

in the execution Environment of ChangeName (), when you execute lines 15th and 16th, you can correctly output the values of name1 and name2 and two variables (called function swapname (), so the values of the two variables have been exchanged with each other), because the name1 In the parent environment (Global Environment) of Changname (), name2 is on its scope chain in his own local environment, that is, name1 and name2. But when the 17th line of code is executed, the error tempname is not defined. Because the parser is not able to find the existence of the variable (the variable tempname is not on its scope chain), it throws an error when it tempname the lookup variable at the scope chain level of the function changename (). Therefore, we can conclude that the parent environment can only access variables and functions in its own environment and in its own environment, and cannot access variables and functions in its child environment.

Similarly, in a global environment, only variables name1, function changename () are stored in variable objects. The parser can only access variables name1 and Functions ChangeName (), but not the variables or functions defined in function changename () and function Swapname (). Therefore, when you execute line 21st and line 22nd, the error that the variable is not defined is thrown. Therefore, the Global environment can only access variables and functions in the global environment and cannot directly access any data in the local environment.

In fact, we can think of the scope chain as such (inside can access the outside, the outside can not access inside, figure for reference):

  

A summary of the relevant knowledge of the scope chain:

1. The execution environment determines the life cycle of the variable and which part of the code can access the variable

2, the execution environment has a global execution Environment (Global environment) and a partial execution environment.

3. Each time a new execution environment is entered, a scope chain for searching for variables and functions is created

4. The local environment of a function can access variables and functions in the scope of a function, or it can access its parent environment, even variables and environments in the global environment.

5. The global environment can only access variables and functions defined in the global environment and cannot directly access any data in the local environment.

6. The execution environment of variables helps to determine that memory should be properly freed.

3. Lifting (hoisting)

To improve the points of variable promotion and function promotion, let's introduce them in turn.

3.1 Variable lift (variable hoisting)

Take a look at the code:

1  var name= "haha"; 2  function ChangeName () {3      console.log (name); 4      var name= "Xixi"; 5  }6  ChangeName (); 7  Console.log (name);

What do you think the results of line 6th and 7th lines of code should be? Well, the answer is: The output results are undefined and haha, respectively. Why the undefined? According to the scope chain of thinking, the output should be the result of haha or xixi ah? (Of course everyone knows that Xixi is not possible because the parser is not aware of the assignment in line 4th when parsing the 3rd line of code).

Let's start by analyzing the scope chain of the Code function ChangeName (): Its own variable object-----> global Variable object. The parser discovers the variable name in the function execution environment and therefore no longer looks for the variable object in the Global environment. However, it is important to note that when parsing the 3rd sentence, the parser does not know the value of the variable name, that is, it knows only the variable name, but does not know its specific value (because it has not executed the 4th sentence code), so the output is undefined, Line 7th output haha Everyone should understand the (scope problem). So the above code can be written in the following form:

1   var name= "haha"; 2   function ChangeName () {3       var name;4       console.log (name); 5       name= "Xixi"; 6  }7  changename (); 8  Console.log (name);

This phenomenon is a variable promotion !

Variable promotion, that is, to promote the variable to the top of the function, it should be noted that the variable promotion is only the declaration of the promotion of variables, not the value of the variable also rise up! See the code above, the most common code is as follows, the function example1 () and the function example2 () are equivalent:

1 function example1 () {2     var a= "haha"; 3     var b= "Xixi"; 4     var c= "Heihei"; 5} 6  7  8 function Examp Le2 () {9     var a,b,c;10     a= "haha"; b= "     Xixi",     c= "Heihei"; 13}


3.2 Function Boost ()

function promotion is the promotion of functions to the front.

There are three ways in which functions are created in javascript: function declarations (static, as in the form of function example1 (), function expressions (volume of letters), function constructs (dynamic, anonymous). The function expression is in the following form:

1 var func1 = function (n1,n2) {2     //function body;3};

The function constructor constructor is in the following form:

var Func2 = new Function ("Para1", "Para2",..., "Function body");    

What needs to be explained here is that only the function declaration form can be promoted! For example:

function declaration Functions MyTest1 () {     func ();     function func () {         Console.log ("I can be promoted");     }} myTest1 ();//Functional expression Functions MyTest2 () {     func ();     var func = function () {         Console.log ("I cannot be promoted");     }} myTest2 ();

The console displays the following results:


The above is what the article describes, welcome to criticize correct!

Simple comprehension of scopes and scope chains in JavaScript (variable elevation)

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.