In the previous post, "JavaScript things-no known pre-explanation" on the pre-interpretation outlined, before writing this blog is going to write a few classic cases, considering that those cases are relatively strong, and gradually have this blog post, This makes it easier to learn and drill down into JavaScript.
Order
A colleague to the interview, the interviewer asked a question: You write a closure I look at? So colleagues rushed to write the following code:
function fn () {alert (' Hello JavaScript Closure!!! '); /mom eggs, E text is not good, to find translation to the closure of the word written out}fn ();
Then the interviewer shook his head and said, "How can this be called closures?" "Finally, the two people are not in dispute, the colleague decisive leave, the interviewer what thing?" (The story is purely fictitious, if there is a coincidence purely coincidental)
Closures may be in the eyes of many people are "tall and bad" technology, it may be in the eyes of many people only such a closure:
Example 1:
function fn () { return function () { alert (' Example 1 ');} } fn () ();
Example 1 PS: This does not look very advanced, it seems that the level of the person is not good oh!
Example 2:
;(function () { alert (' Example 2 ');}) ();
Example 2 PS: This looks more advanced than the previous one, and the first parenthesis is preceded by a semicolon, why add a semicolon, OK, let's leave this question here, and we'll talk about it later.
Example 3:
~FUNCTION fn () { alert (' Example 3 ')} ();
Example 3 PS: This is the most advanced, it is really hanging fried days, I read less, you do not deceive me!
The Lord does not read much, can only write these three kinds of "closures", I believe Bo friends can write more excellent "closure", to this please pause my nonsense, next study the function of the mechanism of operation, it seems that someone already know, it is definitely the scope, I really do not want to add this scope in the title, so total feeling almost mean, This couple of things are all together, why should we repeat them? Old habits, first on the code:
var n = 10;function fn () {alert (n); var n = 9;alert (n);} FN ();
It is easy to say that we draw (the Lord will only use the windows to bring the drawing software, if there is better to ask Bo friends recommended) to analyze:
We see two scopes, one is the window scope (top-level scope), the other is a private scope formed when the FN is called, and what is the scope, the scope is actually the code execution environment. a chestnut, a student his learning environment is the school, equivalent to his scope is the school, if the student is very naughty, at night often fanqiang to the Internet cafes play games, equivalent to form a private environment, this scope is the Internet cafes. All right! This chestnut too tm like the master himself, not by exclamation of a sentence: "An idle youth, grow up dry to kick." Or back to the point, in fact, the definition of the function fn is a description of a piece of code (red box), when the FN call (the green box in the diagram), it will form a scope, of course, the scope of code before the execution will be pre-explained , I'm not going to tell you this. This scope is destroyed when it is executed, and the FN call will also form a new scope, then pre-explain before execution, then execute the code and destroy it after execution.
Understanding closures
We know that a function is called to form a private scope (execution environment) when executed, and this private scope is the closure. look back at the closures or the legendary "Tall and bad"? We look back at the first interview story, and the three examples I wrote, which are actually closures, and the exact three examples are common forms of closures .
Application Scenarios
Now there is a requirement: The HTML page has a UL tag, UL below there are 5 Li tags, require any click on an Li, pop the click of the Li Index (index starting at 0) location, the HTML structure is as follows:
<ul id= "ul" > <li> list 1</li> <li> list 2</li> <li> list 3</li> <li> list 4</li> <li> list 5</li></ul>
Witty I rushed to write the following code:
var lis = document.getElementById (' ul '). getElementsByTagName (' Li '); for (var i = 0, len = lis.length; i < Len; i++) {
lis[i].onclick = function () { alert (i); };}
The final test to see if the requirement is perfect:
Found that no matter how many clicks, the result will eventually pop up, and the expected result is: Click on the list 1 pop-up 0, click on the list 2 popup 1, click on the list 3 pop-up 2 ... At this moment only want to use this picture to describe the current mood:
(When the prototype does not run as designed when it is shown)
How can this be good, why always pop up 5? It's theoretically true! We may as well draw to analyze the following:
In fact, we just give each of the onclick of Li is actually a description string of a function that is saved, this string content is the contents of the red box, if you still do not believe, I have the picture has the truth:
In the Chrome console, enter: Lis[4].onclick, whose value is the description of the function. When we click on the 5th list, it is actually equivalent to Lis[4].onclick (), called the function description, we know that the function will be called to execute the form of a private scope , in this private scope is also pre-interpretation, and then code execution, and then go to find I , I is not present under the current private scope, then I was found under the window scope, so each click POPs up 5.
Obviously the above code does not meet this requirement, our code is not correct, we think about the cause of the problem is what? In fact, the reason is that each time the click is read the window under the I, at this time the value of I is already 5, so the following code:
Way One:
var lis = document.getElementById (' ul '). getElementsByTagName (' li '); function fn (i) { return function () { alert (i); }} for (var i = 0, len = lis.length; i < Len; i++) { Lis[i].onclick = fn (i);}
Way two:
var lis = document.getElementById (' ul '). getElementsByTagName (' Li '); for (var i = 0, len = lis.length; i < Len; i++) {
;(Function (i) { Lis[i].onclick = function () { alert (i); }; }) (i);}
Way three:
var lis = document.getElementById (' ul '). getElementsByTagName (' Li '); for (var i = 0, len = lis.length; i < Len; i++) {
lis[i].onclick = function fn (i) { return function () { alert (i); } } (i);}
Three ways to write in one breath, the idea is the same, is to store this variable I with a private variable, here I will only talk about the way two , of course, understand that one of the rest will understand. In accordance with the Convention, we draw to analyze the following steps:
I have detailed descriptions of the entire code execution, and it is important to note that each Li's onclick attribute is occupied (function (i) {...}). (i) scope, which is not destroyed when the function is executed, because it is occupied by the outside Li (which is under the window scope), so this scope is not destroyed. function () {alert (i) when clicking on any of the Li;} will be executed, it will also form a scope, this scope does not have I, it will go (function () {...}) (i) the scope to find I, finally found in the parameters I, the parameter I value is for the loop simultaneous in; This example cleverly uses closures to store values and perfectly solves the problem.
PS: Just said (function (i) {...}) (i) Why add a semicolon to the front, the reason is to prevent the preceding statement from forgetting to add a semicolon, which causes JavaScript to error parsing, that's all. Of course, one of the above application scenarios is the tabs implementation principle, there can be other implementations, such as the custom attribute mode, through the DOM node relationship to find the index, and the main use of this method is only to deepen the understanding of the closure.
Summarize
Closure is not the legendary tall bad, its core is to understand the function definition, invocation, function calls will form a new private scope, when a scope is occupied outside, then this scope will not be destroyed. The Master of the book is very few, there is not the right place to ask Bo friends to correct, but also thank you for the main article of the support.
JavaScript stuff-big, bad closures.