菜鸟请教关于闭包的问题
先上代码:
(1)html部分:
<dl id="listContainer"> <dt class="click">标题一</dt> <dd class="block">内容一</dd> <dt>标题二</dt> <dd>内容二</dd> <dt>标题三</dt> <dd>内容三</dd> <dt>标题四</dt> <dd>内容四</dd></dl>
*{ margin: 0; padding: 0;} dl{ width: 300px; margin: 100px auto; border: #666 1px solid; border-bottom: none;} dt{ line-height: 40px; background: #888; color: #fff; font-size: 14px; font-weight: bold; padding-left: 20px; border-top: #999 1px solid; border-bottom: #666 1px solid; cursor: pointer;} dt.click{ background: #dfdfdf; color: #333; border-bottom: #cfcfcf 1px solid; border-top: #efefef 1px solid;} dd{ display:none; color: #444; font-size: 12px; text-align: center; padding: 20px; background: #efefef;} dd.block{ display: block; border-bottom:#666 1px solid; } /*分别获取dt,dd标签组*/ var listContainer=document.getElementById('listContainer'), dts=document.getElementsByTagName('dt'), dds=document.getElementsByTagName('dd'); /*(在给点击的dt改变类名,相邻的dd改变类名之前)判断dt.click,dd.block是否存在并设置类名为空*/ function disappear(){ for(var n=0;n<dts.length;n++){ if(dts[n].className=='click'){ dts[n].className=''; } if(dds[n].className=='block'){ dds[n].className=''; } } } /*主要函数---用于隐藏旧选项卡显示新选项卡*/ function clickEffects(){ for(var i=0;i<dts.length;i++){ (function(){ dts[i].onclick=function(){ disappear(); dt[i].className= (this.className!=='click')? 'click':''; dds[i].className= (this.className!=='block')? 'block':''; } })(); } }window.onload=clickEffects; (function(){ dts[i].onclick=function(){ disappear(); dt[i].className= (this.className!=='click')? 'click':''; dds[i].className= (this.className!=='block')? 'block':''; } })(); (function(num){ dts[num].onclick=function(){ disappear(); this.className= (this.className!=='click')? 'click':''; dds[num].className= (this.className!=='block')? 'block':''; } })(i);
其实,click绑定的函数中,i=4这个很好理解,作为闭包取clickEffects活动对象的最终值。但是,为什么在其外部的匿名函数中,i的值不总等于4而是取了i的当前值0,1,2,3?这个外部的匿名函数该怎么对待,难道不是clickEffects的闭包?
[解决办法]
闭包我也不懂,帮顶顺便接分
[解决办法]
function clickEffects(){
for(var i=0;i<dts.length;i++){
(function(num){
dts[i].onclick=function(){
disappear();
dt[i].className= (this.className!=='click')? 'click':'';
dds[i].className= (this.className!=='block')? 'block':'';
}
})(i);
}
}
window.onload=clickEffects;
我来解释下,给添加的外层匿名函数的i是实参,是for循环中的i,当for循环中的i=0,这个i就作为实参传给num这个形参并立即执行,num是一个局部变量,之所以没有消失是因为 dts[i].onclick=function(){
disappear();
dt[i].className= (this.className!=='click')? 'click':'';
dds[i].className= (this.className!=='block')? 'block':'';
}函数引用了外层函数的变量i,当循环多次就产生多个内部函数,每个内部函数都分别引用外部相应的i
[解决办法]
因为for里面的匿名函数并没有形成闭包,匿名函数跟onclick定义的函数的区别就在于i什么时候会被用到。
你把函数改成这样就好理解一些
function clickEffects(){ for(var i=0;i<dts.length;i++){ (function(){ alert(i); } })(); } }