JavaScript closures are a feature, but it is also difficult for many novices to understand. I have read a lot of works, and explain closures differently. Personally, I think the most detailed explanation is given in the book “JavaScript Advanced Programming”. I hope I can help the novice.
Closure example
var count = 10; Function add() {var count = 0; Return function() {count += 1; // Inner scope of function alert(count); } } var s = add() s(); // output 1 s(); 2 / / outputCopy the code
Let’s see what happens. The return value of add() is a function. The first time s() is called, it is the function that executes the return of add(), which is the following function:
function(){ count+=1; // Inner scope of function alert(count); }Copy the code
So if we print count+1, where does count come from? According to the rule of scope chain, variables that are not declared at the bottom of the scope will be searched one level up, returned if they are found, kept looking until the variables of window are not returned, undefined if they are not. So obviously count is the internal count of flag2,
var count=10; Function add(){//var count=0; Return function(){count+=1; // Inner scope of function alert(count); } } var s=add() s(); // output 11 s(); / / output 12Copy the code
The first execution is unquestionable output 1. What about the second execution? Continue to execute the return method of that function, again count+=1; And then I print count, and that’s where the problem is, you don’t want to go up and find count=0; And then print 1? I don’t know if I noticed, but s of alpha performs the following function
function(){ count+=1; // Inner scope of function alert(count); }Copy the code
Rather than
function add(){ var count=0; Return function(){count+=1; // Inner scope of function alert(count); }}Copy the code
So add() is only executed once. Then s() is executed twice, and count is declared only once.
Var s=add(), the function add is only executed here once.
All of this is s(), so where did the second count come from? Yeah, it’s the same variable left over from the first add.
(How is this possible, function variables are released after execution, why is it still there? This is a reference counting problem for the garbage collection mechanism.
If a variable has a non-zero reference, it is not collected by garbage collection.
The first time s(),count is 1, and the second time s(),count is 2.
Let’s go back and see if we can change this function based on what we said above: if we execute add() twice, we should print 1
function add(){ var count=0; Return function(){count+=1; // Inner scope of function alert(count); } } add()(); // output 1 add()(); / / output 1Copy the code
The output is 1 both times. I wonder if you understand closures from this example. Describe the structure of closures and why closures generally require an anonymous function. In order to implement the rule of scope chains, there are two levels of scope. I think you get the idea. Here’s another common mistake
<p>1</p><p>2</p><p>3</p> <p>4</p><p>5</p><p>6</p> var plist=document.getElementsByTagName('p'); for (var i=0; i<plist.length; I ++) {plist[I].onclick=function(){alert(plist[I].innerhtml)}Copy the code
I want to click on the corresponding p to bring up the corresponding I, but what’s going on here, click on any number, it’s undefined, oh my god, shouldn’t it be 1,2,3,4,5,6? So let me explain, after the function is executed, I is 6, right? Plist [6] is undefined. So when we click, we’re firing undefined, but we want the value to be innerHTML of the corresponding P, alert(this.innerhtml)// And that’s fine, this is a nice thing, it points to the current object and when we bind it it’s the current value, Instead of the value of dynamic I, which is bound to a value of dynamic I, you can also use closures, but it’s not recommended, because closures can cause memory to be locked, so the more closures you have, the more memory you use. Use caution.
To summarize, JavaScript closures are formed based on the rules of function variable scope chains and reference counting rules for garbage collection. The nature of JavaScript closures is memory leaks, specifying that memory is not freed. (however, according to the definition of a memory leak is not usable, can not be recycled, this is not a memory leak, because it is not recycled, but can be used, in order to use, do not let the system to reclaim the use of JavaScript closure, private variables, get the corresponding value, etc.).