Deep understanding of JavaScript Series (iii): Scope chain and Closure __java

Source: Internet
Author: User
Tags closure
1. Scope Chain
1. At the time of CreationThe [[Scope]] property of a function contains all of its domain objects when the function is defined.
var name = ' Scope1 ';
 
function Tellscope () {
    console.log (name);//[[Scope]] = [{name: ' Scope1 '}]
}
 
function Testscope () {
    var name = ' Scope2 ';
    Tellscope ();
}
 
Testscope (); Scope1

2) Run time
When a function is invoked, an execution environment (execution context) and the corresponding scope chain are created. Then, use the values of this, arguments, and other named parameters to initialize the active object (activation object) of the function. However, in the scope chain, the active object of the external function is always second, and the external function's active object is in the third position,...... The global execution environment until the end of the scope chain.
function Compare (value1, value2) {
    if (value1 < value2) {
        return-1;
    } else if (value1 > value2) {
  
   return 1;
    } else {return
        0;
    }
}

var result = Compare (5, 10);
  



This leads to two performance optimization methods: 1. Do not use with expression

In general, the scope chain of a run-time context is not changed. However, there are two expressions that can temporarily change the run-time context scope chain at run time. The first one is with an expression.

function Initui () {with
(document) {//avoid!
var bd = body,
links = getelementsbytagname_r ("A"), I = 0,
len = links.length;
while (I < len) {
update (links[i++]);}
getElementById ("Go-btn"). onclick = function () {start ();
};
Bd.classname = "Active";}

When the code flow executes to a with expression, the scope chain of the run-time context is temporarily changed. A new Mutable object is created that contains all the properties of the specified object. This object is inserted at the front end of the scope chain, meaning that all local variables of the function are now pushed into the second scope chain object, so the access cost is higher



By passing the document object to the with expression, a new Mutable object accommodates all the attributes of the document object and is inserted at the front end of the scope chain. This makes access to document properties very fast, but the speed of accessing local variables slows down, such as BD variables. For this reason, it is best not to use the with expression.

The catch clause of a try-catch expression has the same effect in JavaScript, not just with an expression, which artificially alters the scope chain of the run-time context. When an error occurs in a try block, the program flow automatically moves to the catch block and pushes the exception object into a Mutable object at the front of the scope chain. In a catch block, all local variables of a function are now placed in the second scope chain object. For example:

try {methodthatmightcauseanerror ();
} catch (ex) {
     alert (ex.message);//scope chain is augmented

As soon as the catch clause is executed, the scope chain returns to its original state.

A good pattern is to give the error to a dedicated function to handle. Examples are as follows:

try {methodthatmightcauseanerror ();
} catch (ex) {
handleerror (ex);//delegate to Handler method

The

HandleError () function is the only code that runs in a catch clause. This function handles the error freely in the appropriate way and receives the exception object that is generated by the error. Because there is only one statement, no local variable access, the temporary change in the scope chain will not affect the performance of the code.   2. The object members, array entries, and extraterritorial variables that will be used frequently are stored in local variables. The local variables are then accessed faster than those of the original variables. &NBSP for the above example, you can get a performance boost (var doc = document) by simply storing the document in a local variable.  


2. Closures
1. What is a closure, a relationship to a scope chain closures are functions that have access to variables in the scope of another function. A common way to create closures is to create another function inside one function.

First Look at a piece of code:

function Createcomparisonfunction (PropertyName) {return
        function (Object1, object2) {
            var value1 = object1[ PropertyName];
            var value2 = Object2[propertyname];
            if (value1 < value2) {
                return-1;
            } else if (value1 > value2) {return
                1;
            } else {return
                0;
            }
        };
} 
Create function
var comparenames = createcomparisonfunction ("name");
Call function
var result = Comparenames ({name: "Nicholas"}, {name: "Greg"});
Unbind a reference to an anonymous function (in order to free memory)
comparenames = null; 

And the scope chain of these two functions:


A function defined inside another function adds the active object containing the function (that is, the external function) to its scope chain. Therefore, in the scope chain of anonymous functions defined inside the createcomparisonfunction () function, the active object of the external function createcomparisonfunction () is actually included.

After the anonymous function is returned from Createcomparisonfunction (), its scope chain is initialized to the active object and the global variable object that contains the Createcomparisonfunction () function. This allows anonymous functions to access all the variables defined in Createcomparisonfunction (). More importantly, the createcomparisonfunction () function is not destroyed after execution, because the scope chain of the anonymous function still references the active object. In other words, when the createcomparisonfunction () function returns, the scope chain of its execution environment is destroyed, but its active objects remain in memory until the anonymous function is destroyed, createcomparisonfunction () The active object will be destroyed. 2. Closures and Variables

This configuration mechanism of the scope chain leads to a noticeable side effect, that is, the closure can only take the last value of any variable in the function.

function Createfunctions () {
    var result = new Array ();
    for (Var i=0 i < i++) {
        Result[i] = function () {return
                          i;
                    };
    } return result;
}

This function returns an array of functions. On the surface, it seems that each function should return its own index value, that is, the function of position 0 returns 0, and the function of position 1 returns 1, and so on. In practice, however, each function returns 10.

Because the active objects of the createfunctions () function are kept in the scope chain of each function, they refer to the same variable i.

When the Createfunctions () function returns, the value of the variable i is 10, at which point each function references the same variable object that holds the variable i, so the value of I within each function is 10. However, we can force the closure behavior to conform to expectations by creating another anonymous function, as shown below.

function Createfunctions () {
    var result = new Array ();
    for (Var i=0 i < i++) {
        Result[i] = function (num) {return
            function () {return
                              num;
                           } (i);
                } 
    return result;
}

After overriding the previous createfunctions () function, each function returns its own different index values.

In this release, instead of assigning the closure to the array directly, we define an anonymous function and assign the result of executing the anonymous function immediately to the array.

The anonymous function here has a parameter num, which is the value that the final function returns. When we call each anonymous function, we pass in the variable i.

Because function arguments are passed by value, the current value of the variable i is copied to parameter Num. Within this anonymous function, a closure that accesses NUM is created and returned. Thus, each function in the result array has a copy of its own num variable, so it is possible to return different values.

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.