The definition of a closure is very obscure - a closure refers to a paragraph where the syntax domain is located in a specific area and has the ability to continuously refer to (read and write) the value of a non-persistent variable on the execution domain outside its own range within that area. These non-persistent variables of external execution domains magically retain their values (deep links) when the closure was initially defined (or created). Simply put, a closure is to save a copy of variables (key-value pairs) it obtained from the previous level function or scope in another scope, and these key-value pairs will not be destroyed as the execution of the previous level function is completed. Zhou Aimin said it more clearly that a closure is a "attribute table", a closure is a data block, and a closure is a comparison table that stores "Name=Value". It's that simple. However, it must be emphasized that closure is a running period concept.
Closure in Javascript has two characteristics:
As a reference to a function variable - When the function returns, it is in an active state.
A closure is a stack area where no resource is released when a function returns.
There are three types of closure implementations that are more recognized by people.
with(obj){
//This is the object closure
}
(function(){
//Function closure
})()
try{
//...
} catch(e) {
//Catch closure but not in IE
}
Several useful examples
//******************Closure uniqueID******************
uniqueID = (function(){ //The call object of this function saves the value
var id = 0; //This is the value that is private and lasting
//The outer layer function returns a nested function with permission to access the constant value
//That is the nested function we save in the variable uniqueID.
return function(){return id++;}; //Return, add it yourself.
})(); //Call outer function after definition.
(uniqueID()); //0
(uniqueID()); //1
(uniqueID()); //2
(uniqueID()); //3
(uniqueID()); //4
//******************Closure factorial******************
var a = (function(n){
if(n<1){ alert("invalid arguments"); return 0; }
if(n==1){ return 1; }
else{ return n * (n-1); }
})(4);
(a);
function User( properties ) {
// Here you must declare a variable to point to the current instance
var objthis = this;
for ( var i in properties ) {
(function(){
//In the closure, t is new every time, and the value of properties[i] is in for
var t = properties[i];
objthis[ "get" + i ] = function() {return t;};
objthis[ "set" + i ] = function(val) {t = val;};
})();
}
}
//Test code
var user = new User({
name: "Bob",
age: 44
});
alert( ());
alert( ());
("Mike");
alert( ());
alert( ());
( 22 );
alert( ());
alert( ());
Attached the questions I saw in Wuyou today:
Require:
Let the Onclick event of these three nodes correctly pop up the corresponding parameters.
<ul>
<li >aa</li>
<li >aa</li>
<li >aa</li>
</ul>
<script type="text/javascript">
for(var i=1; i < 4; i++){
var id = ("a" + i);
= function(){
alert(i);//Now all return 4
}
}
</script>
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
My explanation is that the scope of the binding function function(){alert(i)} of onclick is the corresponding li object. The scope of the i of alert is window. Each loop is rewritten. Therefore, after the loop, i is already 4, and any li element clicked is 4.
Solution:
Use function closures.
var lists = ("li");
for(var i=0,l=; i < l; i++){
lists[i].onclick = (function(i){//Save in external function function
return function(){
alert(i);
}
})(i);
}
var lists = ("li");
for(var i=0,l=; i < l; i++){
lists[i].onclick = new function(){
var t = i;
return function(){
alert(t+1)
}
}
}
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Utilize event proxy
var ul = ("ul")[0];
= function(){
var e = arguments[0] || ,
target = ? : ;
if(() == "li"){
alert((-1))
}
}
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Keep temporary variables on element nodes.
var lists = ("li");
for(var i=0,t=0,el; el = list[i++];){
= t++
= function(){
alert()
}
}
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Object closure caused by using the with statement.
var els = ("li")
for(var i=0,n=;i<n;i++){
with ({i:i})
els[i].onclick = function() { alert(+i) };
}
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Exception closure constructed using the try...catch statement:
var lists = ("li");
for(var i=0,l=; i < l; i++){
try{
throw i;
}catch(i){
lists[i].onclick = function(){
alert(i)
}
}
}
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
var els = ("li");
(''+Array(+1)).replace(/./g,function(a,i){
els[i].onclick=function(){alert(i)}
})
Closure in Javascript has two characteristics:
As a reference to a function variable - When the function returns, it is in an active state.
A closure is a stack area where no resource is released when a function returns.
There are three types of closure implementations that are more recognized by people.
Copy the codeThe code is as follows:
with(obj){
//This is the object closure
}
Copy the codeThe code is as follows:
(function(){
//Function closure
})()
Copy the codeThe code is as follows:
try{
//...
} catch(e) {
//Catch closure but not in IE
}
Several useful examples
Copy the codeThe code is as follows:
//******************Closure uniqueID******************
uniqueID = (function(){ //The call object of this function saves the value
var id = 0; //This is the value that is private and lasting
//The outer layer function returns a nested function with permission to access the constant value
//That is the nested function we save in the variable uniqueID.
return function(){return id++;}; //Return, add it yourself.
})(); //Call outer function after definition.
(uniqueID()); //0
(uniqueID()); //1
(uniqueID()); //2
(uniqueID()); //3
(uniqueID()); //4
Copy the codeThe code is as follows:
//******************Closure factorial******************
var a = (function(n){
if(n<1){ alert("invalid arguments"); return 0; }
if(n==1){ return 1; }
else{ return n * (n-1); }
})(4);
(a);
Copy the codeThe code is as follows:
function User( properties ) {
// Here you must declare a variable to point to the current instance
var objthis = this;
for ( var i in properties ) {
(function(){
//In the closure, t is new every time, and the value of properties[i] is in for
var t = properties[i];
objthis[ "get" + i ] = function() {return t;};
objthis[ "set" + i ] = function(val) {t = val;};
})();
}
}
//Test code
var user = new User({
name: "Bob",
age: 44
});
alert( ());
alert( ());
("Mike");
alert( ());
alert( ());
( 22 );
alert( ());
alert( ());
Attached the questions I saw in Wuyou today:
Require:
Let the Onclick event of these three nodes correctly pop up the corresponding parameters.
Copy the codeThe code is as follows:
<ul>
<li >aa</li>
<li >aa</li>
<li >aa</li>
</ul>
<script type="text/javascript">
for(var i=1; i < 4; i++){
var id = ("a" + i);
= function(){
alert(i);//Now all return 4
}
}
</script>
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
My explanation is that the scope of the binding function function(){alert(i)} of onclick is the corresponding li object. The scope of the i of alert is window. Each loop is rewritten. Therefore, after the loop, i is already 4, and any li element clicked is 4.
Solution:
Use function closures.
Copy the codeThe code is as follows:
var lists = ("li");
for(var i=0,l=; i < l; i++){
lists[i].onclick = (function(i){//Save in external function function
return function(){
alert(i);
}
})(i);
}
Copy the codeThe code is as follows:
var lists = ("li");
for(var i=0,l=; i < l; i++){
lists[i].onclick = new function(){
var t = i;
return function(){
alert(t+1)
}
}
}
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Utilize event proxy
Copy the codeThe code is as follows:
var ul = ("ul")[0];
= function(){
var e = arguments[0] || ,
target = ? : ;
if(() == "li"){
alert((-1))
}
}
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Keep temporary variables on element nodes.
Copy the codeThe code is as follows:
var lists = ("li");
for(var i=0,t=0,el; el = list[i++];){
= t++
= function(){
alert()
}
}
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Object closure caused by using the with statement.
Copy the codeThe code is as follows:
var els = ("li")
for(var i=0,n=;i<n;i++){
with ({i:i})
els[i].onclick = function() { alert(+i) };
}
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Exception closure constructed using the try...catch statement:
Copy the codeThe code is as follows:
var lists = ("li");
for(var i=0,l=; i < l; i++){
try{
throw i;
}catch(i){
lists[i].onclick = function(){
alert(i)
}
}
}
[Ctrl+A Select all Note:Introducing external Js requires refreshing the page before execution]
Copy the codeThe code is as follows:
var els = ("li");
(''+Array(+1)).replace(/./g,function(a,i){
els[i].onclick=function(){alert(i)}
})