zoukankan      html  css  js  c++  java
  • 关于闭包一个常见的错误

    看下面的一段代码才,从buttons添加不同的click事件:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <script type="text/javascript">
    function func()
    {
        var bts=document.getElementsByTagName("input");
        console.log(bts);
        var values=['text1','text2','text3'];
        for(var i=0;i<bts.length;i++)
        {
            
            (function(){
                bts[i].onclick=function(){
                alert(values[i]);
            }
            
            })();
        }  
        
    }
    
    window.onload=func;
        
    </script>
    </head>
    
    <body>
    <input type="button" value="button1" />
    <input type="button" value="button2" />
    <input type="button" value="button3" />
    
    </body>
    </html>

    我们虽然已经用匿名函数把循环内的代码执行了起来,但是运行时点击button都会显示undefined。我们可以加上这样的语句看到底怎么回事:

      

    在alert(values[i]); 加上console.log(i);

    因为我们的执行函数function(){ }里面的函数alert用到了i变量;

    而我们的i变量有没有指定到一个特定的values[ ]上面。应该这么改:

        for(var i=0;i<bts.length;i++)
        {
            var value=values[i];
            (function(){
                bts[i].onclick=function(){
                alert(value);
            }
            
            })();
        }  
    var value=values[i]; 是关键,我们用了一个变量来记录自执行的匿名函数的作用域内的值

    很多情况下循环内添加事件不能成功原因两个

    1.如果出现结果显示的总是arr.length+1的值,说明我们没有使用自执行的匿名函数来运行
    2.没有使用变量记住该作用域的(凡是用到i)值。
        function addClickListener()
        {
            var countryItems=document.getElementsByClassName("country-item");
            
            //console.log(countryItems);
             
      
        var countryLatLngArr=
            [
             
              [36.83347,118.288422], //toqi
              [31.86502,117.30257], //tochu() 
               [34.356475,108.583374], //toqin()
              [39.981329,116.383667],//toyan()
               [36.617181,114.428101],//tozhao
               [34.761923,114.307251],//towei
               [34.389913,113.712616] //tohan() 
                
             ];
            
             
            for(var i=0;i<countryItems.length;i++)
            {
                (function(){
                    
                    console.log(countryLatLngArr);
                    console.log(i);
                    var temp=i;
                   
                    countryItems[i].getElementsByTagName("td")[0].onclick=function(){
                        /*
                        map.panTo(new google.maps.LatLng(countryLatLngArr[i][0],countryLatLngArr[i][0]));
                        报错Uncaught TypeError: Cannot read property '0' of undefined 
                        */
                        map.panTo(new google.maps.LatLng(countryLatLngArr[temp][0],countryLatLngArr[temp][1]));
                        //要不要加上setCenter();
    
                        
                    }
                })();
            }
        }
        

    最开始用的是

    map.panTo(new google.maps.LatLng(countryLatLngArr[i][0],countryLatLngArr[i][0]),总是报错:
    Cannot read property '0' of undefined;调试时
     console.log(countryLatLngArr);输出是对的啊!为什么报错是undefined?

    panTo()函数里用到了i,但是此时i=arr.length;所以为undefined


  • 相关阅读:
    springboot部署到tomcat
    新建 SecondPresenter 实现类
    BaseFragment 基类
    BaseActivity 基类
    ProxyImpl 类
    BaseFragment 基类代码
    对于大量数据存储入库问题的解决办法
    MainActivity.java 文件
    activity_main.xml 添加自己画的view 组件
    MyView.java 自己画的view
  • 原文地址:https://www.cnblogs.com/youxin/p/2720816.html
Copyright © 2011-2022 走看看