zoukankan      html  css  js  c++  java
  • JS闭包导致循环给按钮添加事件时总是执行最后一个

    加入如下脚本代码: 

    1. <script>    
    2. var list_obj = document.getElementsByTagName('li');    
    3. for (var i = 0; i <= list_obj.length; i++) {          
    4.   list_obj[i].onclick = function() {        
    5.     alert(i);        
    6.   }    
    7. }  
    8. </script>    



    运行后,奇怪的发现无论点击那个li标签,alert出的都是最后一个的内容,5

    下面做下分析:因为在for循环里面指定给list_obj[i].onclick的事件处理程序,也就是onclick那个匿名函数是在for循环执行完成后(用户单击链接时)才被调用的。而调用时,需要对变量i求值,解析程序首先会在事件处理程序内部查找,但i没有定义。然后,又到方法外部去查找,此时有定义,但i的值是4(只有i大于4才会停止执行for循环)。因此,就会取得该值——这正是闭包(匿名函数)要使用其外部作用域中变量的结果。而且,这也是由于匿名函数本身无法传递参数(故而无法维护自己的作用域)造成的。

    那现在原因是知道了,如何来避免这种情况呢?

    既然已经知道函数调用外部变量的时候就构成了一个闭包,里面的变量会受到别的地方的影响,那么我们

    现在要做的就是,构建一个只有自己本身才可访问的闭包,保存只供本身使用的变量

    构建一个闭包很简单,代码如下:

    方式一:

    [javascript] view plain copy
     
    1. var list_obj = document.getElementsByTagName('li');    
    2. for (var i = 0; i <= list_obj.length; i++) {  
    3. <span style="white-space:pre">    </span>list_obj[i].onclick = (function(i){ // outer function  
    4. <span style="white-space:pre">            </span>return function(){ //inner function  
    5. <span style="white-space:pre">                </span>alert(i);  
    6. <span style="white-space:pre">            </span>};  
    7. <span style="white-space:pre">    </span>})(i);    
    8. }*   

    方式二:

    [javascript] view plain copy
     
    1. var list_obj = document.getElementsByTagName('li');    
    2. for (var i = 0; i <= list_obj.length; i++) {    
    3.      
    4.    (function(i){  
    5.         //var p = i      
    6.         list_obj[i].onclick = function() {        
    7.             alert(i);        
    8.         }  
    9.    })(i);  
    10. }   
  • 相关阅读:
    【JavaScript数据结构系列】04-优先队列PriorityQueue
    【JavaScript数据结构系列】02-栈Stack
    【JavaScript数据结构系列】01-数组Array
    【JavaScript数据结构系列】00-开篇
    2019个人年度总结
    批处理·命令行中常用的操作
    flutter 环境出错后排查
    [图解算法]线性时间选择Linear Select——<递归与分治策略>
    阿里云轻量应用服务器——配置MySQL远程连接(踩坑,LAMP+CentOS)
    [知识复习] C语言文件读写
  • 原文地址:https://www.cnblogs.com/tzz-ing/p/5504736.html
Copyright © 2011-2022 走看看