关于js中的所谓的for循环典型问题的剖析,通过现象看本质

来源:互联网 发布:cx域名不值钱吗 编辑:程序博客网 时间:2024/06/15 16:57

由于js语言的特性,所以在js中可能会出现一些有趣的问题。我们这篇博文讨论的for循环问题就是一个很有意思的东东。那么首先我们先要知道这个for循环问题到底指的是什么。

1.首先了解简单的for循环

    <body>    <input type="button" value="按钮1">    <input type="button" value="按钮2">    <input type="button" value="按钮3">    </body>    <script type="text/javascript">    var myIts=document.getElementsByTagName("input");    for(var i=0;i<myIts.length;i++){    myIts[i].onclick=function(){    console.log(i);    }    }    </script>
对于上面代码,当我们分别点击三个按钮的时候,输出结果是三个3。

2.基于上面的for循环代码,我们思考为什么输出是三个3,而不是0,1,2

首先在js中没有块级作用域的概念,所以我们可以这样解析上面for循环的结果,在for循环中的click事件中是没有i变量的,所以按照函数作用域链的规则,会沿着作用域链向上查找,很明显i变量是定义在for循环中,而for循环中的变量是window的,所以这时候在点击button的时候变量i的值就变成了3。

3.关于这个for循环问题的从代码的层面上进行解析

在标题1中的for循环代码中,我们拆开来看,
1.首先for循环第一次执行----------->unction(){console.log(i)}----此时i=0
2.for循环的第二次执行-------------->function(){console.log(i)}----此时i=1
3.for循环的第三次执行-------------->function(){console.log(i)}----此时i=2
4.for循环的第四次执行,此时i=3,不满足if条件,所以停止执行。
5.所以当我们点击按钮的时候,i已经变成了3,所以点击所有的按钮都会输出3。

4.对于这个问题的解决方法

1.在每一次执行的时候,将i的值保存在每一个button中。即
    <body>    <input type="button" value="按钮1">    <input type="button" value="按钮2">    <input type="button" value="按钮3">    </body>    <script type="text/javascript">    var myIts=document.getElementsByTagName("input");    for(var i=0;i<myIts.length;i++){    myIts[i].onclick=function(){    console.log(this.number);    }    myIts[i].number=i;    }    </script>
这样的话点击不同的按钮就会输出不同的i值。

2.使用匿名自执行函数模拟块级作用域
    <body>    <input type="button" value="按钮1">    <input type="button" value="按钮2">    <input type="button" value="按钮3">    </body>    <script type="text/javascript">    var myIts=document.getElementsByTagName("input");    for(var i=0;i<myIts.length;i++){    (function(num){    myIts[num].onclick=function(){    console.log(num);    }    })(i);    }    </script>
这种方法也有人叫做闭包实现,不过我认为的闭包是将函数的内部变量暴露给函数外部,所以对于这种闭包实现的叫法不是很认同,我理解使用匿名自执行函数的这种方法是因为每一个匿名自执行函数都会创建独立的作用域,所以每一个i都会被独立起来。

5.总结

以上就是js中的for循环问题,其实这样的问题挺有意思的,可以加深我们对于js中某些知识的理解。通过现象看本质,对于for循环问题,我们了解这么多就可以了。