JavaScript 循环中的闭包( for循环 i )

jslua不一样,同样的代码在lua中,会分别打印出0,1,2,3,4,但是在js中只会打印54

 

function init() {     

    var pAry = document.getElementsByTagName("p");     

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

        pAry[ i ].onclick = function() {     

            alert( i );     

        }  

    }  

 

即便写成如下形式也不行

 

function init() {     

    var pAry = document.getElementsByTagName("p");     

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

        var temp = i; 

        pAry[ i ].onclick = function() {     

            alert( temp );     

        }  

    }  

 

尽管每一次循环都新建了一个temp,但是都被循环最后一次的temp覆盖。总的来说js的变量作用域不是按照{}来区分的,而是按照函数来区分作用域,故for循环中的onclick函数是共享同一个域的。

(for循环中定义的变量在循环外也可以访问)

 

   

 

解决方式以下几种


1
、将变量 i 保存给在每个段落对象(p)上

function init() {     

    var pAry = document.getElementsByTagName("p");     

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

        pAry[i].i = i;     

        pAry[i].onclick = function() {     

            alert(this.i);     

        }   

    }    

}     

   

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

function init2() {     

    var pAry = document.getElementsByTagName("p");     

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

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

            alert(arguments.callee.i);     

        }).i = i;     

    }   

}     

 

再增加3

   

3、加一层闭包,i以函数参数形式传递给内层函数

function init3() {     

    var pAry = document.getElementsByTagName("p");     

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

        (function(arg){         

            pAry[i].onclick = function() {         

                alert(arg);     

            };     

        })(i);//调用时参数     

    }   

}     

 

   

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

function init4() {     

    var pAry = document.getElementsByTagName("p");     

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

        (function () {     

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

            pAry[i].onclick = function() {

            alert(temp);       

            }     

        })();     

      }  

}     

 

5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)

function init5() {     

    var pAry = document.getElementsByTagName("p");     

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

        pAry[i].onclick = function(arg) {     

            return function() {//返回一个函数     

                alert(arg);     

            }   

        }(i);   

      }   

}    

   

又有一种方法

   

   

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

function init6() {     

    var pAry = document.getElementsByTagName("p");     

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

        pAry[i].onclick = new Function("alert(" + i + ");");//new每次产生一个实例    

    }     

}    

 

   

再增加一种

7、用Function实现,注意与6的区别

function init7() {     

    var pAry = document.getElementsByTagName("p");     

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

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

    }     

}

 

posted @ 2015-09-09 13:01  风沙星辰  阅读(665)  评论(0编辑  收藏  举报