A closure refers to a function that has permission to access variables in another function scope, but the scope configuration mechanism needs to be paid attention to, that is, a closure can only obtain the last value containing any variables in the function.
As in the following cases:
function create(){var arr = new Array(); for (var i=0; i<10; i++){arr[i] = function(){return i;}; }return arr;}var c_arr = create();for(var i=0; i<c_arr.length;i++){document.write("c_arr["+i+"] = "+c_arr[i]()+"<br />"); }Execution results:
On the surface, it seems that the i value returned by each function is different, for example, the value of c_arr[0] should be 0, the value of c_arr[1] should be 1, and so on. Each function can be obtained by returning 10. Why?
Because each function's scope chain stores the active object of the create() function, they all refer to the same variable i. After the for loop ends, the value of i becomes 10. At this time, each function refers to the same variable object that holds the variable i.
We can force the closure to behave as expected by creating another domain function, so that each position corresponds to the corresponding value.
function create(){var arr = new Array(); for (var i=0; i<10; i++){arr[i] = function(num){return function(){return num; };}(i); }return arr;}var c_arr = create();for(var i=0; i<c_arr.length;i++){document.write("c_arr["+i+"] = "+c_arr[i]()+"<br />"); }Execution results:
Define an anonymous function and executes the anonymous function immediately to assign it to the array. Here, the anonymous function has a parameter num, which is the value to be returned by the final function. When calling each function we pass in the variable i. Since the function parameters are passed by value, the current value of variable i will be assigned to the parameter num. Inside this anonymous function, a closure accessing num is created and returned, so that each function in the arr array has a copy of its own num variable, so it can return its own different numerical values.
Classic Examples
Let's look at a classic example. Suppose the page has a set of button tags. We use scripts to bind the click event to this set of button tags, and when clicking, it will pop up which tag is this.
<meta charset="utf-8" /><button>First</button><button>Second</button><button>Third</button><button>Fourth</button><script type="text/javascript">var obj = document.getElementsByTagName('button');for(var i=0;i<obj.length;i++){obj[i].onclick = function(){alert(i);}; }</script>Click each button to result
On the surface, it seems that clicking on each label should pop up different numbers
The first one should pop up 0;
The second one should pop up 1;
And so on.
But the result is that all buttons pop up 4, which is obviously not the result we want.
Let's change the program
<meta charset="utf-8" /><button>First</button><button>Second</button><button>Third</button><button>Fourth</button><script type="text/javascript">var obj = document.getElementsByTagName('button');for(var i=0;i<obj.length;i++){obj[i].onclick = function(num){return function(){alert(num);} }(i); }</script>Click on the second one
Click on the fourth one
We only need to create an anonymous function in the function, which is the same as the above cases. An anonymous function can be implemented to capture the external variable i, and the i value of each button pop is different.