概述
for循环中的闭包问题
在for循环的使用中有时会遇到以下问题:
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
var li=document.getElementsByTagName('li');
for(var j=0;j<li.length;j++){
li[j].onclick=function(){
console.log(j+'-var');
}
}
</script>
不论当我们点击哪一个数字时,控制台输出的都是:
原因是我们触发点击事件的时候for循环已经执行完毕,此时j=6。因此无论我们点击那个li标签都只会打印出4,这时就已经形成了闭包。
闭包是什么?
首先让我们来了解一下什么是闭包,百度百科是这样解释的:闭包是可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。在 Scala、Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby、 Python、Lua、objective c 以及Java(Java8及以上)等语言中都能找到对闭包不同程度的支持。
而我的简单理解就是:一个函数中嵌套了另一个函数,里面的一个函数要访问外层函数的变量,所以就形成了一个闭包,闭包即是为了保留某些局部变量的值而存在的。
解决的几个办法:
1. 给它外加一层闭包
var li=document.getElementsByTagName('li');
for(var i=0;i<li.length;i++){
(function(j){
li[j].onclick=function(){
console.log(j);
}
})(i);
}
2. 在循环内,将i作为数组的一个属性保存起来
var li=document.getElementsByTagName('li');
for(var i=0;i<length;i++){
li[i].index=i;
li[i].onclick=function(){
console.log(this.index);
}
}
3. 改用let局部变量
for(let i=0;i<li.length;i++){
li[i].onclick=function(){
console.log(i+'-let');
}
}
4.采用事件委托
var ul=document.getElementsByTagName('ul')[0];
ul.onclick=function(e){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == "li"){
var li=this.querySelectorAll("li");
var index = Array.prototype.indexOf.call(li,target);
console.log(index);
}
}
以上方法都可以解决闭包问题,个人觉得还是let最方便了
最后
以上就是称心黑米为你收集整理的for循环遍历失败的原因(闭包问题)附四种解决办法完整代码for循环中的闭包问题的全部内容,希望文章能够帮你解决for循环遍历失败的原因(闭包问题)附四种解决办法完整代码for循环中的闭包问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复