【App开发】for循环闭包引发的思考

2020-12-03 08:41:00 1782 1 编辑:深圳网站建设 来源:互联网

深圳App开发.jpg

闭包是指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)

最常用的场景是筛选一组同元素节点给每个元素加上点击事件来弹出各自index索引(回调函数操作)

<ul class="list" id="list">

    <li data-value="360" class="active">360</li>

    <li data-value="qq">qq</li>

    <li data-value="ly">ly</li>

    <li data-value="xiaomi">xiaomi</li>

    <li data-value="huawei">huawei</li>

</ul>

/* 都弹出5 闭包问题 正确的是希望弹出0,1,2,3,4 */

function closure() {     

    var aLis = document.getElementsByTagName("li");     

    for( var i=0; i<aLis.length; i++ ) {     

         aLis[i].onclick = function() {     

         alert(i);     

    }     

  }     

}

closure()

如下是解决闭包的方法12种

将变量 i 保存给在每个对象(li)上

function closure1() {     

    var aLis = document.getElementsByTagName("li");     

    for( var i=0; i<aLis.length; i++ ) { 

         aLis[i].i=i;       

         aLis[i].onclick = function() {     

         alert(this.i);     

    }     

  }     

}

closure1()


setAttribute getAttribute

function closure2() {     

    var aLis = document.getElementsByTagName("li");     

    for( var i=0; i<aLis.length; i++ ) { 

         aLis[i].setAttribute("index",i);       

         aLis[i].onclick = function() {     

            alert(this.getAttribute("index"));     

        }     

  }     

}

closure2()

return function IIFE 传参

function closure3() {     

     var aLis = document.getElementsByTagName("li");     

     for( var i=0; i<aLis.length; i++ ) { 

         aLis[i].onclick=(function(x){

             return function(){

                 alert(x)

             }

         })(i)

     }          

 }

 closure3()

将变量 i 保存在匿名函数自身

function closure4() {     

     var aLis = document.getElementsByTagName("li");     

     for( var i=0; i<aLis.length; i++ ) { 

         (aLis[i].onclick = function() {     

             alert(arguments.callee.i);     

         }).i = i;  

     }          

 }

 closure4()

加一层闭包,i以局部变量形式传递给内存函数

function closure5() {     

     var aLis = document.getElementsByTagName("li");     

     for( var i=0; i<aLis.length; i++ ) { 

         (function () {     

           var temp = i;//调用时局部变量     

           aLis[i].onclick = function() {       

             alert(temp);       

           }     

         })();   

     }          

 }

 closure5()

用Function实现,实际上每产生一个函数实例就会产生一个闭包

function closure6() {     

      var aLis = document.getElementsByTagName("li");     

      for( var i=0; i<aLis.length; i++ ) { 

         aLis[i].onclick = new Function("alert(" + i + ");");//new一次就产生一个函数实例    

      }          

}

closure6()


用Function实现 不new

function closure7() {     

      var aLis = document.getElementsByTagName("li");     

      for( var i=0; i<aLis.length; i++ ) { 

         aLis[i].onclick = Function('alert('+i+')')       

      }          

}

closure7()

bind

function closure8() {     

       var aLis = document.getElementsByTagName("li");     

       for( var i=0; i<aLis.length; i++ ) { 

           aLis[i].addEventListener('click',function(i){

               alert(i)

           }.bind(this,i))     

       }          

}

closure8()

函数调用

function say(index){

     return function(){

       alert(index)

     }

   }

    function closure9() {     

       var aLis = document.getElementsByTagName("li");     

       for( var i=0; i<aLis.length; i++ ) { 

           aLis[i].onclick = say(i) 

       }          

   }

closure9()

函数调用和bind配合

//兼容ie8 不支持bind

 if (!Function.prototype.bind) { 

    Function.prototype.bind = function (oThis) { 

    if (typeof this !== "function") { 

    // closest thing possible to the ECMAScript 5 internal IsCallable function 

    throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); 

    } 

    var aArgs = Array.prototype.slice.call(arguments, 1), 

    fToBind = this, 

    fNOP = function () {}, 

    fBound = function () { 

    return fToBind.apply(this instanceof fNOP && oThis 

    ? this 

    : oThis, 

    aArgs.concat(Array.prototype.slice.call(arguments))); 

    }; 

    fNOP.prototype = this.prototype; 

    fBound.prototype = new fNOP(); 

    return fBound; 

    }; 

    } 

 function say(index){

   alert(index)

 }

 function closure10() {     

    var aLis = document.getElementsByTagName("li");     

    for( var i=0; i<aLis.length; i++ ) { 

        aLis[i].onclick = say.bind(aLis[i],i)

    }          

}


closure10();

事件委托

var addEvent = function(element,type,callback){

        if(element.addEventListener){

            element.addEventListener(type,callback,false);

        }else if(element.attachEvent){

            element.attachEvent('on' + type,callback)

        }

        

    } 

   function closure11() {  

    var oListDom = document.getElementById("list");    

    var aLis = oListDom.getElementsByTagName("li");  

    /* way1 */

    

    oListDom.addEventListener("click",function(e){

      var e = e || window.event;

      var target = e.target || e.srcElemnt;

       for( var i=0; i<aLis.length; i++ ) { 

         if(aLis[i]==target){

         alert(i)

         }

       } 

    })

        /* way2 兼容处理 */

    

    addEvent(oListDom,"click",function(e){

      var e = e || window.event;

      var target = e.target || e.srcElement;

       for( var i=0; i<aLis.length; i++ ) { 

         if(aLis[i]==target){

         alert(i)

         }

       } 

    })


}


closure11()


es6

function closure12() {  

    "use strict";       

    var aLis = document.getElementsByTagName("li");     

    for( var i=0; i<aLis.length; i++ ) { 

        let j = i;//创建一个块级变量

        aLis[i].onclick = function(){

          alert(j)

        }

    }          

}

closure12()


本站文章均为深正网站建设摘自权威资料,书籍,或网络原创文章,如有版权纠纷或者违规问题,请即刻联系我们删除,我们欢迎您分享,引用和转载,但谢绝直接搬砖和抄袭!感谢...
关注深正互联

15

技术从业经验

多一份方案,会有收获...

联系深正互联,免费获得专属《策划方案》及报价

在线咨询 微信交谈
拒绝骚扰,我们只想为给您带来一些惊喜...
多一份免费策划方案,总有益处。

请直接添加技术总监微信联系咨询