Discussion on the problem that js for cycle output i is the same value

  • 2021-07-24 09:57:33
  • OfStack

1. There is a problem in the recent development, why is it that every output is 5, instead of clicking every p, alert will output the corresponding 1, 2, 3, 4 and 5.

The code is as follows:


<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
<title> Closure demo </title> 
</head>  
<body>  
<p>1</p>  
<p>2</p>  
<p>3</p>  
<p>4</p>  
<p>5</p> 
<script type="text/javascript">
window.onload=function() {  
 var ps = document.getElementsByTagName("p");  
 for( var i=0; i<ps.length; i++ ) {  
   ps[i].onclick = function() {  
   alert(i);  
 }  
 }  
}  
</script> 
</body>  
</html>

At this time, clicking any p will pop up 5

Cause: The js event handler will not run when the thread is idle, resulting in the output of the last value of i, that is, 5

2. Solution: Use closures to protect the value of the variable i.


//sava1: Plus 1 Layer closure, i Pass it to the inner function in the form of function parameters  
 for( var i=0; i<ps.length; i++ ) {  
 (function(arg){   
  ps[i].onclick = function() {   
   alert(arg);  
  };  
 })(i);// Call-time parameters   
 } 


//save2: Plus 1 Layer closure, i Pass it to memory function as a local variable  
 for( var i=0; i<ps.length; i++ ) {  
 (function () {  
  var temp = i;// Local variable when called   
  ps[i].onclick = function() {  
  alert(temp);  
  }  
 })();  
 }


//save3: Plus 1 Layer closure, returning 1 Function as a response event (note that it is related to the 3 The subtle differences)  
 for( var i=0; i<ps.length; i++ ) {  
 ps[i].onclick = function(arg) {  
  return function() {// Return 1 Functions   
  alert(arg);  
  }  
 }(i);  
 } 


//save4: Will the variable  i  Save to each paragraph object ( p )   
 for( var i=0; i<ps.length; i++ ) {  
  ps[i].i = i;  
  ps[i].onclick = function() {  
  alert(this.i);  
  }  
 }


//save5: Will the variable  i  Save in anonymous function itself   
 for( var i=0; i<ps.length; i++ ) {  
 (ps[i].onclick = function() {  
  alert(arguments.callee.i);  
 }).i = i;  
 }   
} 


//save6: Use Function Implementation, in fact, every generation 1 Instances of a function are generated 1 Closure 
 for( var i=0; i<ps.length; i++ ) {  
  ps[i].onclick = new Function("alert(" + i + ");");//new1 Secondary generation 1 Function instances  
 } 


//save7: Use Function Implementation, attention and 6 Difference between   
 for( var i=0; i<ps.length; i++ ) {  
   ps[i].onclick = Function('alert('+i+')'); 
 }


Related articles: