What is the closure in JavaScript? What are the application scenarios?

Source: Internet
Author: User
0 reply content: Let's look at an example:

Var foo = (function () {var secret = 'secret'; // functions in the "closure" can access the secret variable, while the secret variable is hidden externally. return {get_secret: function () {// access secret return secret through the defined interface;}, new_secret: function (new_secret) {// modify secret = new_secret ;};} (); foo. get_secret (); // get 'secret' foo. secret; // Type error, access cannot be foo. new_secret ('a new secret'); // Through the function interface, we access and modify the secret variable foo. get_secret (); // get 'a new secret'
The content comes from: How do JavaScript closures work?
I am deeply inspired by the introduction of closures ~

Purpose:
If you can't explain it to a six-year-old, you really don't understand it yourself.
Body
Previously:
There is a princess ......

function princess() {
The closure is a lexical scope created by the function. After the variables created in the closure are referenced, they can be freely used outside the lexical environment. (Https://secure.wikimedia.org/wikipedia/zh/w/index.php? Title = % E9 % 97% AD % E5 % 8C % 85 _ % 28% E8 % AE % A1 % E7 % AE % 97% E6 % 9C % BA % E7 % A7 % 91% E5 % AD % A6 % 29 & variant = zh-cn )

Closures are usually used to create internal variables, so that these variables cannot be arbitrarily modified by the outside, and can be operated through the specified function interface. What is a closure?

Closure refers to Closure. Function objects enclosed by local variables in the external scope are called closures. The closed variable has the same lifecycle as the function object that closes it.


What is a function object?

Function objects are functions used as objects. The objects here refer to data operated by programming languages.


Function objects and closures

Function objects are not necessarily closures.

In C, you can obtain a function pointer and call this function indirectly through the pointer. This is the object in C language (the function object is also the object ). But the function object in C is not a closure-it cannot access local variables in the external scope.

In Javascript, each function has an associated scope chain. Each time you call a JavaScript function, a new object is created for it to save local variables and add the object to the scope chain. When the function returns, delete the object, which is treated as garbage collection. However, if this function defines a nested function and stores it in a certain attribute, it means that an external reference points to this nested function. It will not be treated as garbage collection, and the variable bound to it will not be recycled.

It can be seen that the function object in JavaScript is a closure-the local variables in the external scope can be "closed.


What is an object?

The "object" in the object-oriented model refers to the elements (cats and dogs) in the problem space and their expressions (new Cat () and new Dog () in the solution space ()). Objects are the combination of processes (functions) and data.


Objects and closures

An object contains a process in the form of a method, and a closure contains data in the form of an environment. The so-called "closure is the object of the poor" and "the object is the closure of the poor" means that the function can be implemented in another way by using one of the methods.


Application scenarios

Protect variable security in functions, such as iterators and generators.

Maintain the variable in the memory: if the data is cached, colialized.


----------------------------------------------

My personal summary is based on the future of code, the rhino book, and Thinking in Java.

For example:
Function Counter (start ){
Var count = start;
Return {
Increment: function (){
Count ++;
}, // Function increment

Get: function (){
Return count;
} // Function get
} // Return
} // Function Counter

Var foo = Counter (4 );
Foo. increment ();
Foo. get (); // 5

Here, the Counter function returns two closures: The increment function and the get function. Both functions maintain reference to Counter in the external scope, so you can always access the variable count defined in this scope.

(Example from Article: http://bonsaiden.github.com/JavaScript-Garden/ ) Although many people have answered the question, they have to sort out their ideas based on their own logic. The following answer is a summary of the ideas in the JavaScript authoritative guide.

----------------- Long message warning -------------------------

Conclusion. Closure: The combination of the function object and the scope chain associated with the function

The above definition may not be understood. to describe this concept in detail, we need to explain the concept of scope in JavaScript first.

Variable Scope

A variable scope is a range that is visible in the source code after a variable is defined.

JavaScript has two variable scopes:

Global scope: global variables have a global scope, which is visible throughout JavaScript code.

Local scope:
  • Variables defined in a function are local variables with local scopes. They are completely visible within the defined function body, and function parameters are also counted as local variables of the function.
  • Local variables can overwrite global variables with the same name
  • Functions can be nested, and each function has its own local scope environment.

Example:

/*** Global variable, globally visible */var globalVar = 'global'; var anotherGlobalVar = 'another global var' function fn () {var localVar = 'localscope '; var anotherGlobalVar = 'Global override'; console. log (localVar); console. log (globalVar); console. log (anotherGlobalVar);} fn (); // output: 'local Scope ''' globalScope ''global override' console. log (localVar); // error, localVar does not exist
Closures in JavaScript are inseparable from the Scope Chain feature.
Closure in JavaScript:
Example:
Def foo (){
Var a = 1;
Def bar (){
A = a + 1;
Alert ();
}
Return bar;
}

Var closure = foo (); // at this time, the bar () function is returned, and the variable a in the package is added;
Var closure2 = foo (); // another closure (Instance) is also generated here)
Closure (); // 2
Closure2 (); // 2, bound to another variable
Closure (); // 3

For the general foo () method, the existence of variable a within it should disappear after the foo () method is executed, but foo () the method returns a new method bar (), but this method accesses the variable a of the foo () method (JavaScript accesses the parent attribute through Scope Chain ), the existence of the method bar () prolongs the existence time of the variable a, similar to closing the variable a in its own scope, as long as the method bar () does not expire, then the variable a will always be accompanied by the method bar (), and the Existence Form of the variable a and the method bar () is called the closure;

Closure applications:
In my opinion, although I often hear about the concept of closure, there are not many real applications, and I have not seen or thought of classic applications. in JavaScript, the most commonly used function is probably used as the first class, just like you can var a = new Number (0 ); you can continuously pass a as a Function parameter, or you can var f = new Function (arg1, arg2 ...., functionBody) [new Function ("x", "y", "return (x + y)/2")] to define the Function, then, f is continuously transmitted as a parameter in the function. However, I generally do not allow this function to generate a closure for transmission, instead, it will pass an independent function to avoid having to write more and forget which function it is.

Implementation of JavaScript closure:
As mentioned in the beginning, the closure implementation in JavaScript is inseparable from the Scope Chain in JavaScript. first, there will always be an Execute Context Stack in JavaScript Execution (think about it when the JavaScript interpreter sees an alert (x, if there is no context, how does he know what x is ?), The bottom of the Execute Context Stack must be GlobalContext. Function execution startsThe Execution Context of the Function is added to the stack. The Execution Context consists of three parts:
1. variable Object: stores the vars Variable in the method, the parameters passed in the method, the functions defined in the function, and so on (the function expression is not saved ), variable Object cannot be directly accessed at any time. Of course, different JS engines may provide access interfaces;
2. scope Chain: the Scope Chain used to find the value when this function is executed. This Scope Chain is composed of Variable Object + All Parent Scopes, and Variable Object will be placed at the beginning of this Scope Chain, this is why the variables in the function are first found;
3. thisValue: this object when the function is called. It stores the reference of the function caller (caller;

Variable objects have different definitions under different circumstances, for example, Global objects, and Activation objects in functions;

It is precisely because of the Scope Chain in Execution Context that JavaScript can make in the method bar ()
To enable the method bar () to close the variable a within its own scope so that it will not be followed by foo () method execution is complete and destroyed;

References:
ECMA-262-3In detail. Chapter 1 ~ 6
Http://dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts/ The correct name of a closure is first-class function with lexical scope.

The First-class function determines that the function can be defined within another function and returned as return value.
Lexcial scope indicates that when a name is neither a parameter nor a local variable, the VM will bind it to the local variable of the function-Defined Function runtime. If it is still not up and so on (eventually all functions are defined at the global chunk runtime, so they will be bound from the global variable ).

The environment model in chapter 3 of Structure and Interpretation of Computer Programming is the most accurate description of closures. Each function is defined with a bound environment. Each function is called with a created environment. Bound environment when a function is defined is the created environment when the outer function of this function is called. Local variables are in created environment, and closure variables are in bound environment. This is an application scenario.
Using closures, you can set Private attributes for objects and use Privileged to access private attributes.

  var Foo = function(){      var name = 'fooname';      var age = 12;      this.getName = function(){          return name;      };      this.getAge = function(){          return age;      };  };  var foo = new Foo();  foo.name;        //  => undefined  foo.age;         //  => undefined  foo.getName();   //  => 'fooname'  foo.getAge();    //  => 12
Mid-Autumn Festival in December 2015:
Closure is caused by inconsistent function call stack and scope chain.
Wait for me to finish the work and use my computer to describe it ......

------------------------------
A closure is an entity composed of a function and its referenced external variables.
Because an external variable is referenced, its life is extended. This brings a lot of interesting properties. It can be said that the external function is its mother, And the closure function is its mother.
As mentioned in MDN, a closure associates a function with one or more variables, just like an object in Java, that is, a combination of behavior and attributes.
Therefore, a closure is actually a function, but it is bound to a variable, which is a little more NB-effective than functions without variables.

A special case is that N functions reference the same external variable. In this way, N closures are formed, but because they share external variables, pay special attention to them. For example, a common mistake is to define the closure in the loop, which references the loop variables. It seems that they reference different values. actually they are not. They reference the same variable, and their values are the final values of the cyclic variable. Because js is single-threaded, closure functions must be executed after the loop ends, so the values of the variables referenced by them are the same.
The solution is to re-construct the closure so that they reference different variables, and each variable is initialized to a different value.

In addition, it should be noted that the external variables referenced by the closure function are different from their local variables. The external variables referenced by the function are accompanied by the entire lifecycle of the function, starting from its definition and ending when it is destroyed. However, its local variables are created only when it is called, and the call ends.

Please criticize and correct me!
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.