(Mark) JS in about closures

Source: Internet
Author: User

Closures (Closures)

In ECMAScript, the function is the "First Class" object. This noun means that the function can be passed as a parameter to other functions (in this case, the function is called "Funargs"-the abbreviation for "functional arguments"). A function that receives "Funargs" is called a higher-order function (Higher-order functions), or is more akin to a mathematical concept, called an operator (operators). The runtime of other functions also returns functions, which are called function valued functions (functions with functional value).

There are two conceptual problems with "Funargs" and "functional values", and these two sub-problems are called "Funarg problem" ("functional Parametric Problems"). To solve the problem of functional parameters accurately, it is necessary to introduce the concept of closure (closures). Let's take a closer look at these two issues (we can see that the [[Scope]] property of the function is used in ECMAScript to solve the problem).

"Funarg problem" a sub-problem is "upward funarg problem" [translation: May be translated as: The problem of function parameters looked up]. This problem occurs when a function returns to the outside from other functions. To be able to enter a variable in the external context at the end of the external context, the intrinsic function needs to be stored in the scope of the parent element of the [Scope] property when it is created (at creation moment). Then, when the function is activated, the scope chain of the context behaves as a combination of the activation object and the [Scope] property:

Scope chain = Activation Object += active Object + [[Scope]]

Note that the main thing is that the function saves the external scope when it is created because the saved scope chain (saved scope chain) will be used for variable lookups in future function calls.

functionfoo () {varx = 10; return functionBar () {console.log (x); };} //The return of "Foo" is also a function//and the returned function is free to use the internal variable x varReturnedfunction =foo ();//global variable "x"varx = 20; //support for returned functionReturnedfunction ();//The result is 10, not

This form of scope is called the static scope [static/lexical scope]. The x variable above is the one found in the function bar [[Scope]]. In theory, there will also be dynamic scope [dynamic scope], which means that the above x is interpreted as 20 instead of 10. However, Emcascript does not use dynamic scopes.

Another type of "Funarg problem" is the top-down ["downward funarg problem"]. In this case, the upper and lower of the parent will exist, but there will be ambiguity when judging the value of a variable. That is, which scope this variable should use. Is it scoped at the time of function creation, or is it scoped at execution time? To avoid this ambiguity, you can use closures, which means using static scopes.

Take a look at the following example:

//global variable "x"varx = 10; //Global Functionfunctionfoo () {console.log (x);} (function(funarg) {//local variable "x"  varx = 20; //it doesn't have to be ambiguous.  //because we use the global variable "x" stored in [[Scope]] of the "foo" function,  //is not an "x" of the caller scopeFunarg ();//10, not}) (foo); //pass Foo as a "Funarg"

From the above, we seem to be able to conclude that in the language, the use of static scopes is a mandatory requirement for closures. However, in some languages, a combination of dynamic and static scopes is provided that allows the developer to choose which scope. In ECMAScript, however, only static scopes are used. So ECMAScript fully supports the use of [[Scope]] properties. We can define closures as follows:

A closure is a combination of a code block (in ECMAScript, a function) and statically/lexically saved all parent SC Opes. Thus, via these saved scopes a function may easily refer free variables.

Closures are a series of code blocks (functions in ECMAScript), and the scope of all parents is saved statically. These saved scopes are searched for free variables in the function.

Note that since each normal function is created with [[Scope]], in theory, all functions in ECMAScript are closures.

There is also an important point where several functions may contain the same parent scope (this is a very common case, such as having several internal or global functions). In this case, the variables that exist in [Scope] are shared. Changes to variables in a closure can also affect another closure.

function Baz () {  var x = 1;   return {    functionreturn + +x;}    ,functionreturn -- x;}   var closures = baz (); Console.log (  //  2  closures.bar ()  // 1);

The above code can be represented by this graph:

                      

shared [[Scope]]

When you create multiple functions in a loop, you throw a puzzle. If you use a loop variable (such as "K") in a function that you create, all functions use the same loop variable, causing some programmers to often get no expected value. Now it's clear why this is the problem--because all functions share the same [[Scope]], where the loop variable is the last complex assignment.

var data = for (var k = 0; k < 3; k++) {  function  () {
    
     alert (k);  };} data[
    //  3, but no 0//  3, but not 1//  3, but not 2

There are a number of techniques to solve this kind of problem. One technique is to provide an additional object in the scope chain, such as adding a function:

 var  data = [];  for  (var  k = 0; k < 3; K++ = (function   (x) { return  function   () {alert (x);  }; }) (k);  //  pass K as a parameter in  }  //  result is correct  data[0] (); //  0  data[1] (); //  1  data[2] (); //  

(Mark) JS in about closures

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.