js使用闭包时,内部函数是直接访问外部函数的实际变量而非复制一份新变量

使用闭包时,理解 内部函数是直接访问外部函数的实际变量,而非复制一份新变量是非常重要的 (!).下面是一个错误示范: 

 1 <BODY>  
 2     <INPUT TYPE="button" name='tt' VALUE="按钮1">  
 3     <INPUT TYPE="button" NAME="tt"  VALUE="按钮2">  
 4     <INPUT TYPE="button" NAME="tt" VALUE="按钮3" ONCLICK="">  
 5   
 6  <SCRIPT LANGUAGE="JavaScript">  
 7   <!--  
 8      var add_the_handlers = function(nodes){    
 9         var i;    
10         for(i = 0 ; i < nodes.length ; i ++){    
11               nodes[i].onclick = function(e){    
12                     //(!) 直接访问了外部变量i, 并不是复制一份i的实例。    
13                     //所以随着i一直自增,最后弹出来的均是nodes.length    
14                     alert(i);  //执行按钮点事件的时候  i的值是定义的那个i的值,  
15               }    
16         }    
17   
18         i=9//点击按钮的时候, 弹出 9  
19     }    
20     add_the_handlers(   document.getElementsByName("tt")  )  
21   //-->  
22   </SCRIPT>  

矫正方法: 

 1 <BODY>  
 2 <INPUT TYPE="button" name='tt'    VALUE="按钮1">  
 3 <INPUT TYPE="button" NAME="tt"  VALUE="按钮2">  
 4 <INPUT TYPE="button" NAME="tt"  VALUE="按钮3" >  
 5   
 6  <SCRIPT LANGUAGE="JavaScript">  
 7  <!--  
 8  var add_the_handlers = function(nodes){    
 9 //alert("开始执行")  
10 var i;    
11 for(i = 1 ; i < nodes.length ; i ++){    
12         //alert("执行到for循环中:"+i)  
13         nodes[i].onclick = function(i){    
14             //alert("返回方法之前执行: "+i)  
15              return function(e){ // 返回另一个匿名函数,但是该函数可以访问外面匿名函数构造时传入的 i 实例.    
16                  alert(i);    
17             };    
18     }(i); // 立即调用匿名函数 function(i);    
19 }    
20 //alert("执行结束")  
21 }    
22 add_the_handlers(   document.getElementsByName("tt")  )  
23  //-->  
24  </SCRIPT>  

闭包示例:函数依然可以访问 value的值(闭包). 

 1 <BODY>  
 2  <SCRIPT LANGUAGE="JavaScript">  
 3  <!--  
 4 var myObject_protected = function(){    
 5   
 6         // 这里通过一个函数的形式初始化了对象。由于函数作用域的关系,内部    
 7         // 函数依然可以访问 value的值(闭包).  
 8         var value = 0;    
 9         return {    
10                 increment : function(inc){    
11                     value +=  (typeof inc === 'number'     ? inc : 1);    
12                 },    
13                 getValue : function(){    
14                     return value;    
15                 }    
16          };    
17 };    
18    
19 var myObject_p = new myObject_protected();    
20 myObject_p.increment(10);  //调用一次10  
21 myObject_p.increment(10);  //调用二次20  
22 document.writeln(myObject_p.getValue());    
23  //-->  
24  </SCRIPT>  
25 </BODY>  
原文地址:https://www.cnblogs.com/laj12347/p/2962613.html