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+')');
}