美文网首页
javascript用闭包保存状态

javascript用闭包保存状态

作者: 赠前端 | 来源:发表于2018-02-23 17:57 被阅读0次

    先贴上错误的代码

    var a = [];  
    for(var i=0; i<10; i++){  
      var c = i;  
      a[i] = function(){  
        alert(c);  
      }  
    }  
    a[3]();  
    

    很多人会认为上面这段代码打印出来的会是3;
    结果是9。

    由于i是一个全局变量,a数组里面存的是一个函数,属于一个引用。而i的值一直在增加所以,最后输出来的会是9。

    var a = [];  
    for(var i=0;i<10;i++){  
        var c = i;  
        (function (v){  
            a[i] = function (){  
                alert(v);  
            }  
        })(i);  
          
    }  
    a[3](); 
    

    通过闭包方式保存i的状态来达到输出自己想要的结果

    // 这个代码是错误的,因为变量i从来就没背locked住
    // 相反,当循环执行以后,我们在点击的时候i才获得数值
    // 因为这个时候i操真正获得值
    // 所以说无论点击那个连接,最终显示的都是I am link #10(如果有10个a元素的话)
    
    var elems = document.getElementsByTagName('a');
    for (var i = 0; i < elems.length; i++) {
        elems[i].addEventListener('click', function (e) {
            e.preventDefault();
            alert('I am link #' + i);
        }, 'false');
    }
    
    // 这个是可以用的,因为他在自执行函数表达式闭包内部
    // i的值作为locked的索引存在,在循环执行结束以后,尽管最后i的值变成了a元素总数(例如10)
    // 但闭包内部的lockedInIndex值是没有改变,因为他已经执行完毕了
    // 所以当点击连接的时候,结果是正确的
    
    var elems = document.getElementsByTagName('a');
    for (var i = 0; i < elems.length; i++) {
        (function (lockedInIndex) {
            elems[i].addEventListener('click', function (e) {
                e.preventDefault();
                alert('I am link #' + lockedInIndex);
            }, 'false');
    
        })(i);
    }
    
    // 你也可以像下面这样应用,在处理函数那里使用自执行函数表达式
    // 而不是在addEventListener外部
    // 但是相对来说,上面的代码更具可读性
    
    var elems = document.getElementsByTagName('a');
    for (var i = 0; i < elems.length; i++) {
        elems[i].addEventListener('click', (function (lockedInIndex) {
            return function (e) {
                e.preventDefault();
                alert('I am link #' + lockedInIndex);
            };
        })(i), 'false');
    }
    

    相关文章

      网友评论

          本文标题:javascript用闭包保存状态

          本文链接:https://www.haomeiwen.com/subject/yngxxftx.html