Understanding of JavaScript closures-Han Ye

Source: Internet
Author: User
Tags closure

JavaScript closure is the difficulty of JavaScript, many people on the JS closure is not very understanding, I am the JS closed package at the beginning is also foggy, I just entered Xing ' an effective time, do the positive questions there is a closure to understand the topic. How do you understand JavaScript closures? Let's take a look at the following:

The meaning and understanding of closures

In layman's words, each function in JavaScript is a closure, but the usual sense of nested functions is more capable of reflecting the characteristics of closures, see the following example:

VarGenerateclosure=   function() { VarCount= 0; Var Get = function() {Count++; ReturnCount; }; Return get; }; var counter =. Log (counter ()); //output 1console. (counter ()); //output 2console. (counter ()); //output 3               

In this code, there is a local variable count in the Generateclosure () function, with an initial value of 0. There is also a function called GET, where get adds 1 to the count variable in its parent scope, which is the generateclosure () function, and returns the value of count. The return value of Generateclosure () is the Get function. On the outside we call the Generateclosure () function via the counter variable and get its return value, which is the Get function, which is then repeatedly called counter (), and we find that each return value is incremented by 1.

Let's take a look at the characteristics of the above example, according to the usual imperative programming thinking, count is the variable within the Generateclosure function, and its life cycle is the period when Generateclosure is called, when generateclosure When returned from the call stack, the space requested by the count variable is also freed. The problem is that, after the generateclosure () call ends, counter () references the "already freed" count variable, and instead of making an error, it modifies and returns count each time it calls counter (). What's going on here?

This is the characteristic of the so-called closures. When a function returns a function that is defined internally, a closure is generated, and the closure includes not only the returned function, but also the defined environment of the function. in the example above, when the inner function of the function generateclosure () is referenced by an external variable counter, the local variable of counter and Generateclosure () is a closure. If it's not clear enough, here's an example to help you understand:

VarGenerateclosure=   function() { VarCount= 0; Var Get = function() {Count++; ReturnCount; }; Return Get;};VarCounter1=Generateclosure();VarCounter2=Generateclosure();Console.Log(Counter1()); //output 1console. (counter2 ()); //output 1console. (counter1 ()); //output 2console. (counter1 ()); //output 3console. (counter2 ()); //output 2               

The above example explains how closures are generated: Counter1 and Counter2 call the Generate-closure () function respectively, generating instances of two closures, which are internally referenced by the count variable belonging to their respective operating environment. We can understand that when generateclosure () returns a Get function, the internal variable (that is, the count variable) of the Generateclosure () function that the get may refer to is returned privately, and a copy is generated in memory, and then Generat Eclosure () returns two instances of a function counter1 and counter2 are independent of each other.

Use of closures 1. Nested callback functions

Closures have two main uses, one is to implement nested callback functions, and the other is to hide the details of the object. Let's look at the following code example to learn about nested callback functions. The following code is the use of MongoDB in node. js to achieve a simple increase in the user's functionality (can say that every Nodejs master, usually also JS Master):

Exports.Add_user= function(User_info,Callback) { VarUid=parseint(User_info[' UID ']);Mongodb.Open(function(Err,Db) { If (Err) {Callback(Err); Return;}Db.Collection(' Users ', function(Err,Collection) { If (Err) {Callback(Err); Return;}Collection.Ensureindex("UID", function(Err) { If (Err) {Callback(Err); Return;}Collection.Ensureindex("Username", function(Err) { If (Err) {Callback(Err); Return;}Collection.FindOne({Uid:Uid}, function(Err) { If (Err) {Callback(Err); Return;} If (Doc) {Callback(' Occupied '); } Else { VarUser= {Uid:Uid,User:User_info, }; Collection.insert (user, function (err { Callback (err)  } })  })  })  })      

If you're not familiar with node. js or MongoDB, it doesn't matter that you don't need to understand the details, just look at the approximate logic. This code is nested in the layers of closures, and each layer is nested in a callback function. The callback function does not execute immediately, but waits for the requested function callback after the corresponding request is processed. As we can see, there is a reference to callback in each layer of nesting, and the innermost definition of the UID variable is also used. Due to the existence of the closure mechanism, even if the outer function has been executed, the variable requested in its scope will not be released, because the inner layer function may refer to these variables, which makes it possible to implement nested asynchronous callbacks perfectly.

2. Implementing a Private Member

We know that JavaScript objects do not have private properties, which means that each property of an object is exposed to the outside. This can be a security risk, such as the object's users directly modify a property, resulting in the consistency of the internal data of the object is destroyed, and so on. JavaScript uses a convention to underline all private attributes (for example, _myprivateprop), indicating that the property is private and that the external object should not read and write directly to it. But this is only an informal agreement, assuming that the object's users do not do so, there is no more stringent mechanism? The answer is yes, it can be achieved by closures. Let's take another look at the previous example:

VarGenerateclosure=   function() { VarCount= 0; Var Get = function() {Count++; ReturnCount; }; Return get; };  var counter =  Console. (counter ()); //output 1 Console. (counter ()); //output 2 Console. (counter ()); //output 3               

As we can see, only call counter () to access the count variable within the closure and increase it by 1 according to the rules, it is never possible to find the count variable in other ways. Inspired by this simple example, we can encapsulate an object with a closure and return only an object with an "accessor" to hide the details.

Understanding of JavaScript closures-Han Ye

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.