I recently read several articles about javascript closures, including the recently popular Uncle Tom series and the articles in javascript advanced programming ,...... I can't understand it. Some of the Code is not read in university textbooks, and tianshu is average. Fortunately, I recently met two books, ppk on javascript and object-oriented JavaScript. I am reading the text, but I still recommend reading the original version, the writing is not complex. If you are interested, you can check it out. It is suitable for advanced users.
Today, we will combine these two books to talk about closures in javascript in the simplest language and the most popular way. As they are new users, please point out some mistakes. Thank you.
I. Prerequisites
1. functions are used as function parameters.
When learning javascript, you always need to have a concept that is different from other languages: functions are not special. They are also a type of data, similar to bool, string, number is no different.
Function parameters can be string, number, or bool, for example:
Function (a, B) {return a + B ;}
But you can also pass in functions. You have not heard the error. The function parameter is a function! You can add the following two functions:
Copy codeThe Code is as follows: // double the number of three
Function multiplyByTwo (a, B, c ){
Var I, ar = [];
For (I = 0; I <3; I ++ ){
Ar [I] = arguments [I] * 2;
}
Return ar;
}
Copy codeThe Code is as follows: // Add a number
Function addOne (){
Return a + 1;
}
Then useCopy codeThe Code is as follows: var myarr = [];
// Multiply each number by two and use a loop.
Myarr = multiplyByTwo (10, 20, 30 );
// Add one to each number and use another loop.
For (var I = 0; I <3; I ++) {myarr [I] = addOne (myarr [I]);}
It should be noted that this process uses two loops and there is still room for improvement. It is better to do this:Copy codeThe Code is as follows: function multiplyByTwo (a, B, c, addOne ){
Var I, ar = [];
For (I = 0; I <3; I ++ ){
Ar [I] = addOne (arguments [I] * 2 );
}
Return ar;
}
In this way, the function is passed as a parameter and called directly in the first loop. Such a function is a famous Callback function)
2. function as return value
Return values can be returned in a function, but we are generally familiar with the return of values, suchCopy codeThe Code is as follows: function ex (){
Return 12
}
But once you realize that a function is just a type of data, you can think of returning a function as well. Pay attention to the following function:Copy codeThe Code is as follows: function (){
Alert ('a! ');
Return function (){
Alert ('B! ');
};
}
It returns a pop-up "B !" . Next, use it:Copy codeThe Code is as follows: var newFunc = ();
NewFunc ();
What is the result? When you first execute a (), "A!" is displayed !", NewFunc accepts the return value of a. a function -- newFunc becomes the function returned by a. When newFunc is executed, "B!" is displayed !"
3. javascript Scope
Javascript has a very special scope. It is a function, rather than a block (such as a loop) in other languages. Let's look at the example below:
Var a = 1; function f () {var B = 1; return ;}
If you try to get the value of B at this time: Try to input alert (B) In firebug, you will get the error prompt:
B is not defined
Why do you understand this: your programming environment or window is the top-level function, like a universe, but B is just a variable in your internal function, it is difficult to find a point on a small planet in the universe, so you cannot call it in this environment. On the contrary, this internal function can call variable, because it is exposed to the whole universe, the hacker can hide and call B, because it is inside the function on its own planet.
The above example shows:
Outside f (), a is visible, B is invisible
Within f (), a is visible, and B is also visible.
Complexity:Copy codeThe Code is as follows: var a = 1; // B, c is invisible at this layer
Function f (){
Var B = 1;
Function n () {// a, B, and c can call this n function, because a and B are exposed, and c is internal.
Var c = 3;
}
}
Can function B call the variable c? No. Remember that the javascript scope is in the unit of function. c is inside n, so it is invisible to f.
Start to talk about closures:
First, let's look at the figure:
Assume that G, F, and N represent three levels of functions. a, B, and c are the variables. Based on the scope mentioned above, we draw a conclusion:
- If you are at point A, you cannot reference B, because B is invisible to you.
- Only c can reference B
The Hanging feature of the closure occurs in the following situations:
N broke the limits of F! It ran to the same layer as!Because functions only recognize the environment in which they are defined(This is important, not execution.), C in N can still access B! At this time, a still cannot access B!
But how is this implemented? As follows:
Closure 1:
Copy codeThe Code is as follows: function f (){
Var B = "B ";
Return function () {// a function without a name, so it is an anonymous function.
Return B;
}
}
Note that the returned function can access the variable B in its parent function.
At this time, if you want to obtain the value of B, of course, it is undefined.
But if you do:Copy codeThe Code is as follows: var n = f ();
N ();
You can get the value of B! Although the n function is out of f at this time, B is a variable inside f, but f has an inner ghost and returns the value of B ......
Now, everyone is feeling a little bit.
Closure 2:Copy codeThe Code is as follows: var n;
Function f (){
Var B = "B ";
N = function (){
Return B;
}
}
What if I call f at this time? Then a global range Function of n is generated, but it can access the inside of f and returns the value of B, which is similar to the above!
Closure 3:
You can also use closures to access function parameters.Copy codeThe Code is as follows: function f (arg ){
Var n = function (){
Return arg;
};
Arg ++;
Return n;
}
If:Copy codeThe Code is as follows: var m = f (123 );
M ();
Result 124
At this time, the anonymous function returned in f goes through two new hands. n is given first, and m is assigned to the outside, but the essence is not changed. At the time of definition, the parameter of the parent function is returned.
Closure 4:Copy codeThe Code is as follows: var getValue, setValue;
Function (){
Var secret = 0;
GetValue = function (){
Return secret;
};
SetValue = function (v ){
Secret = v;
};
})
Run:Copy codeThe Code is as follows: getValue ()
0
SetValue (123)
GetValue ()
123
This does not need to be explained. If you have an object-oriented language foundation (such as C #), The getValue and setValue here are similar to the attribute accessors of an object, you can assign values and values through these two accessors, instead of accessing the content.
In fact, there are several examples of closures in the book, but the above four principles are enough to serve as an example. I hope to give javascript beginners a deeper understanding of closures.