一段 js 代码,不知道是什么问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
pouta
V2EX    问与答

一段 js 代码,不知道是什么问题

  pouta 2016-10-31 15:57:44 +08:00 2303 次点击
这是一个创建于 3292 天前的主题,其中的信息可能已经有所发展或是发生改变。
var page = document.getElementsByClassName('swiper-pagination-bullet'); for(var i = 0;i<page.length;i++){ page[i].innerHTML = i+1; page[i].addEventListener('click',function(){ alert(i); //为什么这里 i 的值都等于 page.length }); } 
15 条回复    2016-10-31 17:04:22 +08:00
ycycwx
    1
ycycwx  
   2016-10-31 16:01:46 +08:00 via iPhone
好经典的面试题...
mlkr
    2
mlkr  
   2016-10-31 16:05:14 +08:00 via Android
var 作用域的问题 ,换成 let 试试
clearbug
    3
clearbug  
   2016-10-31 16:07:10 +08:00 via Android
好经典的面试题。。。你需要去看看闭包
pouta
    4
pouta  
OP
   2016-10-31 16:13:55 +08:00
@ycycwx 不是面试题 是我自己写的时候 遇到的坑
wubotao
    5
wubotao  
   2016-10-31 16:20:52 +08:00
因为执行点击事件时, i 的值已经变成了 page.length
i 不是取运行时的值,而是取 for 循环完成之后的值
wubotao
    6
wubotao  
   2016-10-31 16:21:44 +08:00
@mlkr 不是作用域的问题,是代码执行顺序的问题。
Sunyanzi
    7
a href="/member/Sunyanzi" class="dark">Sunyanzi  
   2016-10-31 16:24:24 +08:00
萌新你好 ... 槽点太多其实不太知道该从何说起 ... 我试试看用最简单的方法跟你解释下吧 ...

Javascript 是一门只有「函数作用域」而没有「块级作用域」的语言 ...

你的变量也好闭包也罢 ... 只要它们是被定义在同一个函数里的 ... 就会始终各自指向同样的地址 ...

解决方法也很简单 ... 另开一个域就好 ... 方法如下 ...

page[i].addEventListener('click',( function( i ) {
return function() {
alert(i); // 这样就不会相等啦
}
} )( i );
Sunyanzi
    8
Sunyanzi  
   2016-10-31 16:31:26 +08:00   1
一言以蔽之 ... 你的做法虽然看起来不像 ... 但其实就是把同一个闭包绑定了五次 ...

我的做法则创建了五个不同的闭包 ... 只有这一点区别 ... 如果你愿意更深入了解的话 ... 去看 this 吧 ...
pouta
    9
pouta  
OP
   2016-10-31 16:37:02 +08:00
@wubotao 说到点了
ferrum
    10
ferrum  
   2016-10-31 16:37:59 +08:00
感觉每个不认真看书的 Javascript 学习者都会遇到这样的问题……
learnshare
    11
learnshare  
   2016-10-31 16:40:11 +08:00
经典,可以看看 let 和 var 的差异,以及闭包
pouta
    12
pouta  
OP
   2016-10-31 16:44:48 +08:00
@Sunyanzi 谢谢你的耐心解答 最终我是这么写的
var page = document.getElementsByClassName('swiper-pagination-bullet');
for(var i = 0;i<page.length;i++){
page[i].innerHTML = i+1;
page[i].addEventListener('mouseover',function(){
var toPage = this.innerHTML;
mySwiper.slideTo(toPage,1000,true);
});
}
pouta
    13
pouta  
OP
   2016-10-31 16:46:24 +08:00
@ferrum 我不是前端
yoa1q7y
    14
yoa1q7y  
   2016-10-31 16:49:59 +08:00
这样解释比较清楚
addEventListener 中的匿名函数,在这个 for 循环时并不会执行,而 i 始终只有一个,等到 for 循环完成时, i 就变成了 page.length ,等触发点击,执行函数的时候,取到的自然就是 page.length
pouta
    15
pouta  
OP
   2016-10-31 17:04:22 +08:00
@yoa1q7y 嗯 很清楚
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2823 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 28ms UTC 14:20 PVG 22:20 LAX 06:20 JFK 09:20
Do have faith in what you're doing.
ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86