JavaScript scope chain Detailed

Source: Internet
Author: User
Tags closure

JavaScript scope chain is still very tasty, understand this knowledge point, closure of the problem will be solved

1. JavaScript global variables and local variables

First of all, the first look at the JS global variables and local variables, JS is not a block-level scope, so you can not learn the knowledge of C + + scope in JS!

(1) Global variables

JS Global variables can also be seen as the properties of the Window object, this sentence how to understand, see the following code:

var x = ten; alert (window.x); // pop up Ten

i.e. var x = 10; equivalent to window.x=10;

Look at the code again.

function foo () {    = ten;} Foo (); alert (window.x);

What's this going to pop up? Answer is 10!

If you do not use the keyword var when defining a variable in a function, you are actually defining a global variable. You'll often see a point in front-end optimization: Define as few global variables as possible! If a global variable is unavoidable, it is saved in a local variable. Like this:

function foo () {    var doc = document;     var divobj = doc.getelementbytagname (' div ');}

Save the Document object in the local variable doc, and then manipulate the doc.

But, the question is, why does it improve efficiency? Let's keep this question, and then look at the scope chain before we finish.

(2) Local variables

To say block-level scopes, there is only a function block in JS, the variables defined in the function are local variables, of course, must have a keyword var! (no keyword VAR is defined as a global variable)

This means that the IF Else statement and the variables created in the For loop can be accessed externally to the

function foo () {    var x = 1;}  for (var i = 0;i<10;i++) {    }if(i) {    var y = ten;} Foo (); alert (i); // tenalert (y); // Tenalert (x); // error x is not defined

2. Scope Chain

This is the focus, what is the scope chain, or the code to explain

var x = 1; function foo () {    var y = 2;         function Bar () {        var z = 3;        Alert (x+y+z);    }    Bar ();} Foo ();

The answer is not to mention that, in the bar function does not have Y and Z, when executing x+y+z, JS search x, y, z variable is a mechanism of the scope chain, this example of the search order: Bar->foo->window

The front is too simple, maybe some people can not see, a little dry.

The scope chain of bar is:

Barscopechain = [    bar]. AO,    foo. AO,    Global. VO];

The scope chain of Foo is:

Fooscopechain = [    foo. AO,    Global. VO];

Perhaps you crossing will be confused, may ask, this ao,vo, what is a thing? Let's take a look at the variable bar function variable search process

For example: To find the x variable, the bar function searches for the variable x, first from its own AO object, if bar. AO has this attribute, then the value of this property is used directly, and if it does not exist, it goes to the parent function's AO object, which is foo. AO

If the x attribute is found, it is used and cannot be found to continue at global. Vo Object Lookup, find the property of X, return the property value. If at global. If it is not found in Vo, an exception Referenceerror will be thrown.

  During the execution of a function, each time a variable is encountered, it retrieves from where the data is fetched and stored, from the scope chain head, that is, starting from the active object, looking for an identifier with the same name, if a variable corresponding to the identifier is found, and if not, continues to search for the next object in the scope chain. If all objects are not found after searching, the identifier is considered undefined, and each identifier undergoes such a search process during function execution.

Knowing this, looking back at the first question, why not define global variables and optimize them?

Because the scope chain is the structure of the stack, global variables at the bottom of the stack, each access to the global variable will traverse the stack, which will certainly affect efficiency.

When the function is created, each function creates an active object, active objects (AO), Global object (VO), and the process of creating the function is the process of adding properties to the object, and the scope chain is made up of the active objects that bind the properties.

During the execution of the function, the execution context of the function is created, and there is no explanation here, so you can look at Uncle Tom's deep understanding of the JavaScript series

The execution context is a dynamic concept that is created when the function is run, the active object is also a dynamic concept, it is referenced by the scope chain of the execution context, and it can be concluded that both the execution context and the active object are dynamic concepts, And the scope chain of the execution context is initialized by the function scope chain. PS: These concepts are the internal mechanism of JS engine parsing code, external is inaccessible!

  

Or just that piece of code, let's look at the JS engine compilation process, to learn more about how the scope chain is created

Functions go Global, create VO objects, bind x properties < stack > (this is just pre-parsing, properties declared for the AO object binding, the function executes the assignment statement, so the value is Underfind)

Global. VO = {   x:underfind;    function  }

Encounter the Foo function to create Foo. VO, bind Y property < Enter stack >

Foo. AO = {   y:undefined;    function  }

Next is the bar function, Z Properties < stack >

Bar. AO = {   z:undefined;}

Both the scope chain and the execution context are saved in the stack, so

The scope chain of the bar function is [0]bar. Ao-->[1]foo. Ao-->[2]global. VO

The scope chain of the Foo function is [0]foo. Ao-->[1]global. VO

Here's an equation:scope=ao| VO + [[scope]]

The function scope equals its own AO object plus the parent scope, or it can be understood that the scope of a function equals its active object plus the parent scope.

3, to see a closure example

My intention is to give each Li tag a click event, click to pop up the corresponding index, the single will actually pop up each time "This is the fourth Li tag"

Analysis: foo When creating the Foo function. Ao={liobj:undefined,i:undefined,onclick:refeerence of Function}

In the function execution, the anonymous function itself does not have the I variable, so will go to Foo's active object to find I variable, when the for loop is executed, the value of the variable i has changed, so always output 4

So how do you solve this problem? It's simple, too.

The first solution:

Use a function to save the variable I can

Second workaround:

Careful people will definitely find a way, is to put the global variables in the local save

Last point: The prototype chain takes precedence over the scope chain when a variable is found. JS engine first in the function AO object lookup, and then to the prototype chain lookup, followed by the scope chain.

Not finished, today is really no feeling, brain is very messy, or go out, through the air, there is no place also hope good-hearted people pointed out.

JavaScript scope chain Detailed

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.