最近在做项目时遇到调用for循环中i取值问题,主要代码如下:
function delete__listen() {
var detNum=document.getElementsByTagName('li');
for(var i = 0; i < detNum.length; i++){
detNum[i].onclick = function(){
alert(i);
delete__item(i);
}
}
}
function delete__item(k) {
data.splice(k,1);
getNum(data);
}
发现问题:
此代码块的主要目的是想每次点击对应目标时弹出对应的数字下标 0~n,但实际是无论点击哪个目标都会弹出数字n+1。
分析主要原因,发现+1的原因在于for循环中,当执行指针到达闭包阈值发现没有触发click事件,以此循环体循环完毕,i++,因此当click函数被触发时看到alert弹出出现n+1的结果;内部闭包域引用外部闭包域的私有变量作为变量,当外部闭包域的私有变量内容发生变化,内部闭包域得到的值自然会发生改变。
解决方案:
为当前数组项即当前li对象添加一个名为count的属性,值为循环体的i变量的值,此时当前li对象的count属性并不是对循环体的i变量的引用,而是一个独立li对象的属性,属性值在声明的时候就确定了。代码如下:
for(var i = 0; i < detNum.length; i++){
detNum[i].count=i; /*good*/
detNum[i].onclick = function(){
delete__item(this.count);
}
}
主要思路来源于:用9种办法解决 JS 闭包经典面试题之 for 循环取 i